Merge branch 'trunk'
This commit is contained in:
commit
bf98cfc545
89 changed files with 3192 additions and 1121 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -19,3 +19,4 @@ storage/crm_migration.csv
|
|||
MIG/errors_sql.txt
|
||||
public/js
|
||||
public/css
|
||||
public/assets
|
||||
|
|
|
|||
|
|
@ -95,9 +95,10 @@ class ApiError extends BaseEnumRoutable
|
|||
'customerExists' => 'L\'utilisateur est déjà enregistré sur ce site',
|
||||
'customerNotActivated' => 'Le compte n\'est pas activé',
|
||||
'customerAlreadyActive' => 'Le compte est déjà activé',
|
||||
'singleOptinCustomerExists' => 'Le signle optin ne peut être ajouté car un compte existe.',
|
||||
'authFailed' => 'Echec de l\'authentification',
|
||||
'singleOptinCustomerExists' => 'Le single optin ne peut être ajouté car un compte existe.',
|
||||
'authFailed' => 'Echec de l\'authentification du compte',
|
||||
'needAuth' => 'Vous devez être authentifié',
|
||||
'apiAuthFailed' => 'Echec de l\'authentification client à l\'Api LDC-CRM pour ce service',
|
||||
'methodNotAllowed' => 'This method is not allowed for this request',
|
||||
'wrongTimeStamp' => 'Your request is malformed, please check timestamp header and parameter',
|
||||
'missingParameter' => 'The request is missing some parameters',
|
||||
|
|
|
|||
33
app/Enums/CustomerExportType.php
Normal file
33
app/Enums/CustomerExportType.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnumRoutable;
|
||||
|
||||
/**
|
||||
* @method static self singleOptin()
|
||||
* @method static self customer()
|
||||
* @method static self both()
|
||||
*
|
||||
* @package LDCCrmClient
|
||||
* @subpackage enums
|
||||
*/
|
||||
class CustomerExportType extends BaseEnumRoutable
|
||||
{
|
||||
public static function values(): array
|
||||
{
|
||||
return [
|
||||
'singleOptin' => 1,
|
||||
'customer' => 2,
|
||||
'both' => 3
|
||||
];
|
||||
}
|
||||
public static function labels(): array
|
||||
{
|
||||
return [
|
||||
'singleOptin' => trans('Les single optins uniquement'),
|
||||
'customer' => trans('Les clients uniquement acceptant de recevoir les newsletters'),
|
||||
'both' => trans('La totalité des client acceptant de recevoir les newsletters')
|
||||
];
|
||||
}
|
||||
}
|
||||
42
app/Http/Controllers/AnswerController.php
Normal file
42
app/Http/Controllers/AnswerController.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Answer;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
|
||||
class AnswerController extends Controller
|
||||
{
|
||||
use CrudController {
|
||||
index as crudIndex;
|
||||
}
|
||||
|
||||
/** @var Log */
|
||||
public static $modelClass = Answer::class;
|
||||
|
||||
public static $layout = 'layouts.app';
|
||||
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
$parent = request()->question;
|
||||
if ($parent) {
|
||||
$query->whereHas('question', function ($q) use ($parent) {
|
||||
return $q->whereId($parent->id);
|
||||
});
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function index(CrudIndexRequest $request)
|
||||
{
|
||||
/** @var \Illuminate\View\View */
|
||||
$view = $this->crudIndex($request);
|
||||
if ($request->ajax()) {
|
||||
return $view;
|
||||
}
|
||||
return view('answer.index', $view->getData());
|
||||
}
|
||||
}
|
||||
|
|
@ -3,29 +3,28 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ManageBrandRequest;
|
||||
use App\Models\Brand;
|
||||
use Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
|
||||
class BrandController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$brands = Brand::all();
|
||||
return view('brands.index', compact('brands'));
|
||||
use CrudController {
|
||||
index as crudIndex;
|
||||
}
|
||||
|
||||
public function manage(ManageBrandRequest $request, Brand $brand)
|
||||
{
|
||||
if ($request->isMethod('post')) {
|
||||
if (!$brand) {
|
||||
$brand = new Brand($request->validated());
|
||||
} else {
|
||||
$brand->fill($request->validated());
|
||||
}
|
||||
$brand->save();
|
||||
return redirect()->route('brands')->with('success', trans('Modifications enregistrées !'));
|
||||
}
|
||||
/** @var Brand */
|
||||
public static $modelClass = Brand::class;
|
||||
|
||||
return view('brands.manage', compact('brand'));
|
||||
public static $layout = 'layouts.app';
|
||||
|
||||
public function index(CrudIndexRequest $request)
|
||||
{
|
||||
/** @var \Illuminate\View\View */
|
||||
$view = $this->crudIndex($request);
|
||||
if ($request->ajax()) {
|
||||
return $view;
|
||||
}
|
||||
return view('brand.index', $view->getData());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,17 +2,108 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CustomerExportType;
|
||||
use App\Http\Requests\CustomerExport;
|
||||
use App\Models\Brand;
|
||||
use App\Models\Customer;
|
||||
use App\Models\CustomerInfo;
|
||||
use App\Models\CustomerLogin;
|
||||
use App\Models\SingleOptin;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use League\Csv\Writer;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class CustomerController extends Controller
|
||||
{
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
$brands = Brand::select('id', 'name')->get();
|
||||
return view('customers.index', compact('brands'));
|
||||
$modelTable = (new Customer())->getTable();
|
||||
$modelClass = Customer::class;
|
||||
$brands = Brand::select('id', 'name')->get();
|
||||
$columns = ['customer_infos.lastname', 'customer_infos.firstname'];
|
||||
|
||||
// Jointure pour pouvoir trier les colonnes
|
||||
/** @var \Illuminate\Database\Eloquent\Builder */
|
||||
$query = CustomerInfo::join('customer_logins', function (JoinClause $join) {
|
||||
$join->on('customer_logins.brand_id', '=', 'customer_infos.brand_id')
|
||||
->on('customer_logins.customer_id', '=', 'customer_infos.customer_id');
|
||||
})
|
||||
->join('customers', function (JoinClause $join) {
|
||||
$join->on('customers.id', '=', 'customer_infos.customer_id');
|
||||
})
|
||||
->join('brands', function (JoinClause $join) {
|
||||
$join->on('brands.id', '=', 'customer_infos.brand_id');
|
||||
});
|
||||
if (request()->brand or Session::has("crud.$modelTable.brand")) {
|
||||
$brand = $request->brand ?? Session::get("crud.$modelTable.brand");
|
||||
Session::put("crud.$modelTable.brand", $brand);
|
||||
$query = $query->where('customer_infos.brand_id', $brand);
|
||||
}
|
||||
|
||||
// Search on crud Label column
|
||||
if ($request->search or Session::has("crud.$modelTable.search")) {
|
||||
$search = $request->search ?? Session::get("crud.$modelTable.search");
|
||||
Session::put("crud.$modelTable.search", $search);
|
||||
$query->where(function ($q) use ($columns, $search) {
|
||||
foreach ($columns as $column) {
|
||||
$q = $q->orWhere($column, 'LIKE', "%$search%");
|
||||
}
|
||||
$q = $q->orWhere('customers.email', 'LIKE', "%$search%");
|
||||
$q = $q->orWhere('customer_logins.last_connection', 'LIKE', "%$search%");
|
||||
});
|
||||
}
|
||||
|
||||
// Sort columns
|
||||
if ($request->sort_col) {
|
||||
Session::put("crud.$modelTable.sort_col", $request->sort_col);
|
||||
}
|
||||
if ($request->sort_way) {
|
||||
Session::put("crud.$modelTable.sort_way", $request->sort_way);
|
||||
}
|
||||
|
||||
if ($request->rst) {
|
||||
Session::remove("crud.$modelTable.brand");
|
||||
Session::remove("crud.$modelTable.search");
|
||||
Session::remove("crud.$modelTable.sort_way");
|
||||
Session::remove("crud.$modelTable.sort_col");
|
||||
}
|
||||
if (
|
||||
Session::has("crud.$modelTable.sort_col") and
|
||||
Session::has("crud.$modelTable.sort_way") and
|
||||
(Schema::hasColumn($modelTable, Session::get("crud.$modelTable.sort_col")) or
|
||||
in_array(Session::get("crud.$modelTable.sort_col"), [
|
||||
'brands.name',
|
||||
'customers.email',
|
||||
'customer_infos.firstname',
|
||||
'customer_infos.lastname',
|
||||
'customer_infos.opt_in',
|
||||
'customer_logins.last_connection',
|
||||
'customer_logins.status'
|
||||
]))
|
||||
) {
|
||||
$query = $query->orderBy(
|
||||
Session::get("crud.$modelTable.sort_col"),
|
||||
Session::get("crud.$modelTable.sort_way")
|
||||
);
|
||||
}
|
||||
|
||||
/** @var \Illuminate\Pagination\AbstractPaginator */
|
||||
$customers = $query->paginate(config('crud.paginate', 50));
|
||||
|
||||
// use a crud controller (any) to gather crudModels
|
||||
$modelsClasses = (new BrandController())->getCrudModels();
|
||||
return view('customer.index', compact(
|
||||
'modelsClasses',
|
||||
'modelClass',
|
||||
'modelTable',
|
||||
'customers',
|
||||
'brands'
|
||||
));
|
||||
}
|
||||
|
||||
public function show(Customer $customer, Brand $brand)
|
||||
|
|
@ -21,48 +112,14 @@ class CustomerController extends Controller
|
|||
->where('brand_id', $brand->id)->firstOrFail();
|
||||
$customerLogin = CustomerLogin::where('customer_id', $customer->id)
|
||||
->where('brand_id', $brand->id)->first();
|
||||
return view('customers.show', compact('customerInfos', 'customerLogin'));
|
||||
}
|
||||
|
||||
public function filter($texte, Brand $brand = null)
|
||||
{
|
||||
if ($brand) {
|
||||
$customers = Customer::join('customer_infos', 'customers.id', '=', 'customer_infos.customer_id')
|
||||
->join('customer_logins', 'customers.id', '=', 'customer_logins.customer_id')->select(
|
||||
'customer_infos.customer_id',
|
||||
'customer_infos.firstname',
|
||||
'customer_infos.lastname',
|
||||
'customer_infos.opt_in',
|
||||
'customers.email',
|
||||
'customer_infos.brand_id',
|
||||
'customer_logins.last_connection'
|
||||
)->where([
|
||||
['lastname', 'like', '%' . $texte . '%'],
|
||||
['customer_infos.brand_id', $brand->id],
|
||||
['customer_logins.brand_id', $brand->id]
|
||||
])->orWhere([
|
||||
['email', 'like', '%' . $texte . '%'],
|
||||
['customer_infos.brand_id', $brand->id],
|
||||
['customer_logins.brand_id', $brand->id]
|
||||
])->get();
|
||||
} else {
|
||||
$customers = CustomerInfo::join('customers', 'customers.id', '=', 'customer_infos.customer_id')
|
||||
->join('customer_logins', function ($join) {
|
||||
$join->on('customer_logins.customer_id', '=', 'customer_infos.customer_id');
|
||||
$join->on('customer_logins.brand_id', '=', 'customer_infos.brand_id');
|
||||
})->select(
|
||||
'customer_infos.customer_id',
|
||||
'customer_infos.firstname',
|
||||
'customer_infos.lastname',
|
||||
'customer_infos.opt_in',
|
||||
'customers.email',
|
||||
'customer_infos.brand_id',
|
||||
'customer_logins.last_connection'
|
||||
)->where('lastname', 'like', '%' . $texte . '%')
|
||||
->orWhere('email', 'like', '%' . $texte . '%')->get();
|
||||
}
|
||||
|
||||
return response()->json($customers);
|
||||
// use a crud controller (any) to gather crudModels
|
||||
$modelsClasses = (new BrandController())->getCrudModels();
|
||||
return view('customer.show', compact(
|
||||
'modelsClasses',
|
||||
'customerInfos',
|
||||
'customerLogin'
|
||||
));
|
||||
}
|
||||
|
||||
public function delete(Customer $customer, Brand $brand)
|
||||
|
|
@ -77,6 +134,104 @@ class CustomerController extends Controller
|
|||
$customer->delete();
|
||||
}
|
||||
|
||||
return redirect()->route('customers')->with('success', "Compte supprimé.");
|
||||
return redirect()->route('customers.index')->with('success', "Compte supprimé.");
|
||||
}
|
||||
|
||||
public function export()
|
||||
{
|
||||
// use a crud controller (any) to gather crudModels
|
||||
$modelsClasses = (new BrandController())->getCrudModels();
|
||||
$brands = Brand::all();
|
||||
return view('customer.export', compact(
|
||||
'brands',
|
||||
'modelsClasses'
|
||||
));
|
||||
}
|
||||
|
||||
public function exportSubmit(CustomerExport $request)
|
||||
{
|
||||
$pagination = 2000;
|
||||
$header = '"lastname";"firstname";"email";"hashcode"';
|
||||
|
||||
$w = Writer::createFromString($header . PHP_EOL);
|
||||
$w->setDelimiter(';');
|
||||
$w->setEnclosure('"');
|
||||
$w->setOutputBOM(Writer::BOM_UTF8);
|
||||
|
||||
$exportType = CustomerExportType::make(\intval($request->export_type));
|
||||
|
||||
//We send the CSV using Symfony StreamedResponse
|
||||
$response = new StreamedResponse();
|
||||
$response->headers->set('Content-Encoding', 'none');
|
||||
$response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
|
||||
$response->headers->set('Description', 'File Transfer');
|
||||
$response->headers->set(
|
||||
'Content-Disposition',
|
||||
sprintf(
|
||||
'attachment; filename="Export pour newsletter %s %s.csv"',
|
||||
Carbon::now()->format('d-m-Y_H-i'),
|
||||
Str::slug($exportType)
|
||||
)
|
||||
);
|
||||
|
||||
switch ($exportType) {
|
||||
case CustomerExportType::both():
|
||||
$continue = true;
|
||||
// continue
|
||||
case CustomerExportType::customer():
|
||||
$i = 0;
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $req */
|
||||
$req = CustomerInfo::where('brand_id', $request->brand);
|
||||
$total = $req->count();
|
||||
$pages = $total / $pagination;
|
||||
do {
|
||||
/** @var \Illuminate\Pagination\LengthAwarePaginator $items */
|
||||
$items = $req->with('customer', function ($q) {
|
||||
$q->select(['id', 'email']);
|
||||
})->paginate(
|
||||
$pagination,
|
||||
['lastname', 'firstname', 'hashcode', 'customer_id'],
|
||||
'page',
|
||||
$i
|
||||
);
|
||||
$items->map(function (CustomerInfo $customerInfo) use ($w) {
|
||||
$w->insertOne([
|
||||
'lastname' => $customerInfo->lastname,
|
||||
'firstname' => $customerInfo->firstname,
|
||||
'email' => $customerInfo->customer->email,
|
||||
'hashcode' => $customerInfo->hashcode
|
||||
]);
|
||||
});
|
||||
} while ($i++ <= $pages);
|
||||
if (!isset($continue)) {
|
||||
break;
|
||||
}
|
||||
// continue
|
||||
case CustomerExportType::singleOptin():
|
||||
SingleOptin::where('brand_id', $request->brand)->get()
|
||||
->map(function (SingleOptin $singleOptin) use ($w) {
|
||||
$w->insertOne([
|
||||
'lastname' => '',
|
||||
'firstname' => '',
|
||||
'email' => $singleOptin->email,
|
||||
'hashcode' => ''
|
||||
]);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
//we create a callable to output the CSV in chunk
|
||||
//with Symfony StreamResponse you can flush the body content if necessary
|
||||
//see Symfony documentation for more information
|
||||
$flush_threshold = 1000; //the flush value should depend on your CSV size.
|
||||
$response->setCallback(function () use ($w, $flush_threshold) {
|
||||
foreach ($w->chunk(1024) as $offset => $chunk) {
|
||||
echo $chunk;
|
||||
if ($offset % $flush_threshold === 0) {
|
||||
flush();
|
||||
}
|
||||
}
|
||||
});
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class LoginController extends Controller
|
|||
$request->remember !== null ? true : false
|
||||
)
|
||||
) {
|
||||
return redirect()->route('customers');
|
||||
return redirect()->route('customers.index');
|
||||
} else {
|
||||
return back()->withInput($request->except("password"))
|
||||
->withErrors("Les identifiants entrés sont incorrects, veuillez réessayer.");
|
||||
|
|
|
|||
125
app/Http/Controllers/QuestionController.php
Normal file
125
app/Http/Controllers/QuestionController.php
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\QuestionExport;
|
||||
use App\Models\Brand;
|
||||
use App\Models\Question;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
use League\Csv\Writer;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class QuestionController extends Controller
|
||||
{
|
||||
use CrudController {
|
||||
index as crudIndex;
|
||||
}
|
||||
|
||||
/** @var Question */
|
||||
public static $modelClass = Question::class;
|
||||
|
||||
public static $layout = 'layouts.app';
|
||||
|
||||
public function index(CrudIndexRequest $request)
|
||||
{
|
||||
/** @var \Illuminate\View\View */
|
||||
$view = $this->crudIndex($request);
|
||||
if ($request->ajax()) {
|
||||
return $view;
|
||||
}
|
||||
return view('question.index', $view->getData());
|
||||
}
|
||||
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
if (request()->brand) {
|
||||
$query = $query->where('brand_id', '=', request()->brand);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function export()
|
||||
{
|
||||
$brands = Brand::all();
|
||||
return view('question.export', compact('brands'));
|
||||
}
|
||||
|
||||
public function exportSubmit(QuestionExport $request)
|
||||
{
|
||||
$results = [];
|
||||
$brand = Brand::findOrFail($request->brand);
|
||||
$questions = $brand->questions->load('answers');
|
||||
|
||||
foreach ($questions as $question) {
|
||||
$answersCounts = DB::query()
|
||||
->selectRaw('count(*) as total, answer_id')
|
||||
->from('customer_answer')
|
||||
->whereIn('answer_id', $question->answers->pluck('id'))
|
||||
->groupBy('answer_id')
|
||||
->get()->keyBy('answer_id');
|
||||
|
||||
$results[$question->id] = [
|
||||
'question' => $question->question,
|
||||
'answers' => []
|
||||
];
|
||||
foreach ($question->answers as $answer) {
|
||||
$results[$question->id]['answers'][] =
|
||||
[
|
||||
"$answer->answer ",
|
||||
$answersCounts[$answer->id]->total ?? 0
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$pagination = 2000;
|
||||
|
||||
$w = Writer::createFromString('');
|
||||
$w->setDelimiter(';');
|
||||
$w->setEnclosure('"');
|
||||
$w->setOutputBOM(Writer::BOM_UTF8);
|
||||
|
||||
//We send the CSV using Symfony StreamedResponse
|
||||
$response = new StreamedResponse();
|
||||
$response->headers->set('Content-Encoding', 'none');
|
||||
$response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
|
||||
$response->headers->set('Description', 'File Transfer');
|
||||
$response->headers->set(
|
||||
'Content-Disposition',
|
||||
sprintf(
|
||||
'attachment; filename="Export pour newsletter %s %s.csv"',
|
||||
Carbon::now()->format('d-m-Y_H-i'),
|
||||
Str::slug($brand->name)
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($results as $result) {
|
||||
$w->insertOne([
|
||||
'question' => $result['question'],
|
||||
]);
|
||||
foreach ($result['answers'] as $answer) {
|
||||
$w->insertOne($answer);
|
||||
}
|
||||
$w->insertOne([]);
|
||||
}
|
||||
|
||||
//we create a callable to output the CSV in chunk
|
||||
//with Symfony StreamResponse you can flush the body content if necessary
|
||||
//see Symfony documentation for more information
|
||||
$flush_threshold = 1000; //the flush value should depend on your CSV size.
|
||||
$response->setCallback(function () use ($w, $flush_threshold) {
|
||||
foreach ($w->chunk(1024) as $offset => $chunk) {
|
||||
echo $chunk;
|
||||
if ($offset % $flush_threshold === 0) {
|
||||
flush();
|
||||
}
|
||||
}
|
||||
});
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,49 +2,45 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\ManageServiceRequest;
|
||||
use App\Models\Brand;
|
||||
use App\Http\Requests\GenerateApiToken;
|
||||
use App\Mail\ServiceCredentialRenewed;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
|
||||
class ServiceController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$services = Service::all();
|
||||
return view('services.index', compact('services'));
|
||||
use CrudController {
|
||||
index as crudIndex;
|
||||
}
|
||||
|
||||
public function manage(ManageServiceRequest $request, Service $service = null)
|
||||
/** @var Service */
|
||||
public static $modelClass = Service::class;
|
||||
|
||||
public static $layout = 'layouts.app';
|
||||
|
||||
public function index(CrudIndexRequest $request)
|
||||
{
|
||||
$brands = Brand::all();
|
||||
$edit = $service ? true : false;
|
||||
|
||||
if ($request->isMethod('post')) {
|
||||
if (!$service) {
|
||||
$service = new Service($request->validated());
|
||||
} else {
|
||||
$service->fill($request->validated());
|
||||
}
|
||||
$brand = Brand::findOrFail($request->brand_id);
|
||||
$service->brand()->associate($brand);
|
||||
$service->save();
|
||||
|
||||
return redirect()->route('services')->with('success', $edit ? 'Modifications enregistrées !' : sprintf(
|
||||
'Token du service : \'%s\'',
|
||||
$service->bearer_token
|
||||
));
|
||||
/** @var \Illuminate\View\View */
|
||||
$view = $this->crudIndex($request);
|
||||
if ($request->ajax()) {
|
||||
return $view;
|
||||
}
|
||||
|
||||
return view('services.manage', compact('service', 'brands', 'edit'));
|
||||
return view('service.index', $view->getData());
|
||||
}
|
||||
|
||||
public function generateApiToken(Service $service)
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
public function generateApiToken(GenerateApiToken $request, Service $service)
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
$bearerToken = $service->generateBearerToken();
|
||||
$bearerPwd = $service->bearer_pwd;
|
||||
$service->saveOrFail();
|
||||
Mail::send(new ServiceCredentialRenewed($service, $user));
|
||||
return back()
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
->with('success', "Nouveau token d'API de $service->name : '$bearerToken' et mot de passe '$bearerPwd'");
|
||||
->with('error', "ATTENTION : METTEZ À JOUR LE SITE ! \nNouveau token d'API de $service->name : '$bearerToken' et mot de passe '$bearerPwd'");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
38
app/Http/Controllers/SingleOptinController.php
Normal file
38
app/Http/Controllers/SingleOptinController.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\SingleOptin;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
|
||||
class SingleOptinController extends Controller
|
||||
{
|
||||
use CrudController {
|
||||
index as crudIndex;
|
||||
}
|
||||
|
||||
/** @var SingleOptin */
|
||||
public static $modelClass = SingleOptin::class;
|
||||
|
||||
public static $layout = 'layouts.app';
|
||||
|
||||
public function index(CrudIndexRequest $request)
|
||||
{
|
||||
/** @var \Illuminate\View\View */
|
||||
$view = $this->crudIndex($request);
|
||||
if ($request->ajax()) {
|
||||
return $view;
|
||||
}
|
||||
return view('single_optin.index', $view->getData());
|
||||
}
|
||||
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
if (request()->brand) {
|
||||
$query = $query->where('brand_id', request()->brand);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Resources\StatusResource;
|
||||
use App\Models\Brand;
|
||||
use App\Models\SingleOptin;
|
||||
|
||||
class SingleOptinsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$brands = Brand::select('id', 'name')->get();
|
||||
return view('single-optins.index', compact('brands'));
|
||||
}
|
||||
|
||||
public function filter($texte, $brandId = null)
|
||||
{
|
||||
if ($brandId !== null) {
|
||||
$customers = SingleOptin::where([['email', 'like', '%' . $texte . '%'], ['brand_id', $brandId]])->get();
|
||||
} else {
|
||||
$customers = SingleOptin::where('email', 'like', '%' . $texte . '%')->get();
|
||||
}
|
||||
|
||||
return response()->json($customers);
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
// TODO : Gestion avec les stats
|
||||
$optin = SingleOptin::find($id);
|
||||
if ($optin) {
|
||||
$optin->delete();
|
||||
}
|
||||
return new StatusResource(['status' => "OK"]);
|
||||
}
|
||||
}
|
||||
41
app/Http/Requests/CustomerExport.php
Normal file
41
app/Http/Requests/CustomerExport.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Enums\CustomerExportType;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CustomerExport extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'brand' => 'required|numeric|exists:brands,id',
|
||||
'export_type' => [
|
||||
'required',
|
||||
'numeric',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if (!\in_array($value, CustomerExportType::values())) {
|
||||
$fail(trans('Le type d\'export invalide'));
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
30
app/Http/Requests/GenerateApiToken.php
Normal file
30
app/Http/Requests/GenerateApiToken.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class GenerateApiToken extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
30
app/Http/Requests/QuestionExport.php
Normal file
30
app/Http/Requests/QuestionExport.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class QuestionExport extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'brand' => 'required|numeric|exists:brands,id'
|
||||
];
|
||||
}
|
||||
}
|
||||
55
app/Mail/ServiceCredentialRenewed.php
Normal file
55
app/Mail/ServiceCredentialRenewed.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Service;
|
||||
use App\Models\User;
|
||||
use Illuminate\Mail\Mailable;
|
||||
|
||||
class ServiceCredentialRenewed extends Mailable
|
||||
{
|
||||
|
||||
/**
|
||||
* The concerned service
|
||||
*
|
||||
* @var \App\Models\Service
|
||||
*/
|
||||
public $service;
|
||||
|
||||
/**
|
||||
* The user who did the action
|
||||
*
|
||||
* @var \App\Models\User
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Service $service, User $user)
|
||||
{
|
||||
$this->service = $service;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->view('mail.service-renewed')
|
||||
->subject('!!! Warning !!!, New service credential have been generated !')
|
||||
->text('mail.service-renewed-plain')
|
||||
->with('appName', config('app.name'))
|
||||
->with('service', $this->service)
|
||||
->with('by', sprintf('%s %s (%s)', $this->user->firstname, $this->user->lastname, $this->user->email))
|
||||
->to(
|
||||
config('mail.contactsList.serviceweb', 'equipe.web@ldc.fr'),
|
||||
sprintf('%s service warning', config('app.name'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,15 +4,45 @@ namespace App\Models;
|
|||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudType;
|
||||
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
|
||||
|
||||
class Answer extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'answer';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'answer'
|
||||
];
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'answer' => [
|
||||
'label' => Str::ucfirst(trans('models.common.answer')),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'min:1',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Question BelongsTo relation
|
||||
*
|
||||
|
|
|
|||
|
|
@ -4,13 +4,22 @@ namespace App\Models;
|
|||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudType;
|
||||
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
|
||||
use Rennokki\QueryCache\Traits\QueryCacheable;
|
||||
|
||||
class Brand extends Model
|
||||
{
|
||||
use IsCrudModel;
|
||||
use HasFactory;
|
||||
use QueryCacheable;
|
||||
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $cacheFor = 0;
|
||||
|
||||
protected $fillable = [
|
||||
|
|
@ -20,6 +29,34 @@ class Brand extends Model
|
|||
public function __construct(array $attributes = [])
|
||||
{
|
||||
$this->cacheFor = config('api.servicesDBCache') * 60;
|
||||
|
||||
self::$editableProperties = [
|
||||
'name' => [
|
||||
'label' => Str::ucfirst(trans('models.common.name')),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'min:5',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'services' => [
|
||||
'label' => Str::ucfirst(Str::plural(trans('models.classes.services'))),
|
||||
'type' => CrudType::belongsToMany(),
|
||||
'belongsToMany' => Service::class,
|
||||
'belongsToManyLabel' => 'name',
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,16 @@ class CustomerInfo extends Model
|
|||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* get Login
|
||||
*
|
||||
* @return \App\Models\CustomerLogin
|
||||
*/
|
||||
public function login()
|
||||
{
|
||||
return $this->customer->login($this->brand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Brand BelongsTo relation
|
||||
*
|
||||
|
|
|
|||
|
|
@ -5,12 +5,21 @@ namespace App\Models;
|
|||
use App\Enums\QuestionType;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudType;
|
||||
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
|
||||
use Kwaadpepper\Enum\Traits\CastsEnums;
|
||||
|
||||
class Question extends Model
|
||||
{
|
||||
use CastsEnums;
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'question';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $enumCasts = [
|
||||
'type' => QuestionType::class
|
||||
|
|
@ -21,6 +30,57 @@ class Question extends Model
|
|||
'type'
|
||||
];
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'question' => [
|
||||
'label' => Str::ucfirst(trans('models.common.question')),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'min:10',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'type' => [
|
||||
'label' => Str::ucfirst(trans('models.common.type')),
|
||||
'type' => CrudType::enum(),
|
||||
'enum' => QuestionType::class,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'brand_id' => [
|
||||
'label' => Str::ucfirst(trans('models.classes.brand')),
|
||||
'type' => CrudType::belongsTo(),
|
||||
'belongsTo' => Brand::class,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'answers' => [
|
||||
'label' => Str::ucfirst(Str::plural(trans('models.classes.answers'))),
|
||||
'type' => CrudType::belongsToMany(),
|
||||
'belongsToMany' => Answer::class,
|
||||
'belongsToManyLabel' => 'answer',
|
||||
'actions' => [
|
||||
CrudAction::view()
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Brand BelongsTo relation
|
||||
*
|
||||
|
|
|
|||
|
|
@ -8,13 +8,21 @@ use Illuminate\Database\Eloquent\Model;
|
|||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudType;
|
||||
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
|
||||
use Rennokki\QueryCache\Traits\QueryCacheable;
|
||||
|
||||
class Service extends Model
|
||||
{
|
||||
use IsCrudModel;
|
||||
use HasFactory;
|
||||
use QueryCacheable;
|
||||
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $cacheFor = 0;
|
||||
|
||||
protected $fillable = [
|
||||
|
|
@ -24,6 +32,32 @@ class Service extends Model
|
|||
public function __construct(array $attributes = [])
|
||||
{
|
||||
$this->cacheFor = config('api.servicesDBCache') * 60;
|
||||
|
||||
self::$editableProperties = [
|
||||
'name' => [
|
||||
'label' => Str::ucfirst(trans('models.common.name')),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'min:5',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'brand_id' => [
|
||||
'label' => Str::ucfirst(trans('models.classes.brand')),
|
||||
'type' => CrudType::belongsTo(),
|
||||
'belongsTo' => Brand::class,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view()
|
||||
]
|
||||
],
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,15 +4,76 @@ namespace App\Models;
|
|||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudType;
|
||||
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
|
||||
|
||||
class SingleOptin extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'email';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'email'
|
||||
];
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'email' => [
|
||||
'label' => Str::ucfirst(trans('models.common.email')),
|
||||
'type' => CrudType::email(),
|
||||
'validate' => [
|
||||
'required',
|
||||
'email:rfc,dns',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
$q = static::query();
|
||||
if (request()->user) {
|
||||
$q = $q->where('id', '!=', $this->id);
|
||||
}
|
||||
if ($q->where('email', $value)->exists()) {
|
||||
$fail(__(':attribute est déjà utilisé', [
|
||||
'attribute' => $attribute
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'brand_id' => [
|
||||
'label' => Str::ucfirst(trans('models.classes.brand')),
|
||||
'type' => CrudType::belongsTo(),
|
||||
'belongsTo' => Brand::class,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view()
|
||||
]
|
||||
],
|
||||
'created_at' => [
|
||||
'label' => Str::ucfirst(trans('models.common.optinDate')),
|
||||
'type' => CrudType::string(),
|
||||
'readonly' => true,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Brand BelongsTo relation
|
||||
*
|
||||
|
|
|
|||
29
app/Policies/AnswerPolicy.php
Normal file
29
app/Policies/AnswerPolicy.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Policies\Rules\UserStaticRules as USR;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class AnswerPolicy extends RootPolicy
|
||||
{
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPolicies()
|
||||
{
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'answer' => [
|
||||
'viewAny' => USR::make('everyOne'),
|
||||
'update' => USR::make('everyOne'),
|
||||
'create' => USR::make('everyOne'),
|
||||
'delete' => USR::make('everyOne')
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
28
app/Policies/BrandPolicy.php
Normal file
28
app/Policies/BrandPolicy.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Policies\Rules\UserStaticRules as USR;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class BrandPolicy extends RootPolicy
|
||||
{
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPolicies()
|
||||
{
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'brand' => [
|
||||
'viewAny' => USR::make('everyOne'),
|
||||
'update' => USR::make('everyOne'),
|
||||
'create' => USR::make('everyOne')
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -4,12 +4,33 @@ namespace App\Policies;
|
|||
|
||||
use App\Models\Customer;
|
||||
use App\Models\Service;
|
||||
use App\Policies\Rules\UserStaticRules as USR;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class CustomerPolicy
|
||||
class CustomerPolicy extends RootPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPolicies()
|
||||
{
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'customer' => [
|
||||
'viewAny' => USR::make('everyOne'),
|
||||
'view' => USR::make('everyOne'),
|
||||
'delete' => USR::make('everyOne')
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function customerBelongsToService(Service $service, Customer $customer)
|
||||
{
|
||||
return !\is_null($customer->login($service->brand));
|
||||
|
|
|
|||
30
app/Policies/QuestionPolicy.php
Normal file
30
app/Policies/QuestionPolicy.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Policies\Rules\UserStaticRules as USR;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class QuestionPolicy extends RootPolicy
|
||||
{
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPolicies()
|
||||
{
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'question' => [
|
||||
'viewAny' => USR::make('everyOne'),
|
||||
'view' => USR::make('everyOne'),
|
||||
'update' => USR::make('everyOne'),
|
||||
'create' => USR::make('everyOne'),
|
||||
'delete' => USR::make('everyOne')
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
17
app/Policies/Rules/UserStaticRules.php
Normal file
17
app/Policies/Rules/UserStaticRules.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies\Rules;
|
||||
|
||||
use Kwaadpepper\CrudPolicies\Policies\Rules\StaticRules;
|
||||
|
||||
/**
|
||||
* Userlevel Policiy Static Rules
|
||||
*! Rules has to return boolean value
|
||||
*/
|
||||
abstract class UserStaticRules extends StaticRules
|
||||
{
|
||||
protected static function everyOne(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
29
app/Policies/ServicePolicy.php
Normal file
29
app/Policies/ServicePolicy.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Policies\Rules\UserStaticRules as USR;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class ServicePolicy extends RootPolicy
|
||||
{
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPolicies()
|
||||
{
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'service' => [
|
||||
'viewAny' => USR::make('everyOne'),
|
||||
'view' => USR::make('everyOne'),
|
||||
'update' => USR::make('everyOne'),
|
||||
'create' => USR::make('everyOne')
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
27
app/Policies/SingleOptinPolicy.php
Normal file
27
app/Policies/SingleOptinPolicy.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Policies\Rules\UserStaticRules as USR;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class SingleOptinPolicy extends RootPolicy
|
||||
{
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPolicies()
|
||||
{
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'singleoptin' => [
|
||||
'viewAny' => USR::make('everyOne'),
|
||||
'delete' => USR::make('everyOne')
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,11 @@
|
|||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
|
|
@ -31,5 +35,14 @@ class AppServiceProvider extends ServiceProvider
|
|||
if (!in_array(config('app.env'), ['local', 'testing'])) {
|
||||
URL::forceScheme('https');
|
||||
}
|
||||
|
||||
Paginator::useBootstrap();
|
||||
|
||||
$appInfos = Cache::remember('composer', 360, function () {
|
||||
return json_decode(File::get(\app_path('../composer.json')));
|
||||
});
|
||||
View::share('name', $appInfos->name);
|
||||
View::share('version', $appInfos->version);
|
||||
View::share('license', $appInfos->license);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,13 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Answer;
|
||||
use App\Models\Brand;
|
||||
use App\Models\Customer;
|
||||
use App\Models\CustomerInfo;
|
||||
use App\Models\Question;
|
||||
use App\Models\Service;
|
||||
use App\Models\SingleOptin;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
|
|
@ -36,6 +41,12 @@ class RouteServiceProvider extends ServiceProvider
|
|||
Route::middleware('web')->namespace($this->namespace)->group(base_path('routes/web.php'));
|
||||
});
|
||||
|
||||
Route::model('brand', Brand::class);
|
||||
Route::model('service', Service::class);
|
||||
Route::model('single_optin', SingleOptin::class);
|
||||
Route::model('question', Question::class);
|
||||
Route::model('answer', Answer::class);
|
||||
|
||||
Route::bind('customer', function ($value) {
|
||||
if (\ctype_digit($value)) {
|
||||
$customer = Customer::where('id', '=', $value)->firstOrFail();
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b208c78b97e68c078345620a5a023186a1753ee8
|
||||
Subproject commit b29fb6a5bc1a2740c3ce5276ff1d38199eed539c
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "ldc/ldccrmv2client",
|
||||
"type": "project",
|
||||
"version": "2.1.5",
|
||||
"version": "2.1.7",
|
||||
"description": "LDC CRM V2",
|
||||
"authors": [
|
||||
{
|
||||
|
|
@ -32,11 +32,14 @@
|
|||
"fideloper/proxy": "^4.4",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"kwaadpepper/crud-policies": "^0.1.17",
|
||||
"kwaadpepper/enum": "^2.0",
|
||||
"laravel-lang/lang": "~7.0",
|
||||
"laravel/framework": "^8.39",
|
||||
"laravel/tinker": "^2.5",
|
||||
"rennokki/laravel-eloquent-query-cache": "^3.0"
|
||||
"league/csv": "^9.7",
|
||||
"rennokki/laravel-eloquent-query-cache": "^3.0",
|
||||
"spatie/laravel-mix-preload": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^2.5",
|
||||
|
|
@ -81,6 +84,7 @@
|
|||
"prefer-stable": true,
|
||||
"scripts": {
|
||||
"test": [
|
||||
"echo 'check memcached is running';netcat -z localhost 11211",
|
||||
"@configclear",
|
||||
"./test.sh"
|
||||
],
|
||||
|
|
|
|||
609
composer.lock
generated
609
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "0df11a64ace2bcbbbc3710af5cc6868f",
|
||||
"content-hash": "52ddf0e771e6661178474f2a87aeaf7e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "arondeparon/laravel-request-sanitizer",
|
||||
|
|
@ -128,16 +128,16 @@
|
|||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.9.2",
|
||||
"version": "0.9.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/brick/math.git",
|
||||
"reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0"
|
||||
"reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0",
|
||||
"reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae",
|
||||
"reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -147,7 +147,7 @@
|
|||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "^2.2",
|
||||
"phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0",
|
||||
"vimeo/psalm": "4.3.2"
|
||||
"vimeo/psalm": "4.9.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
|
@ -172,15 +172,19 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/brick/math/issues",
|
||||
"source": "https://github.com/brick/math/tree/0.9.2"
|
||||
"source": "https://github.com/brick/math/tree/0.9.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/BenMorel",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/brick/math",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-01-20T22:51:39+00:00"
|
||||
"time": "2021-08-15T20:50:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cache/adapter-common",
|
||||
|
|
@ -447,16 +451,16 @@
|
|||
},
|
||||
{
|
||||
"name": "composer/package-versions-deprecated",
|
||||
"version": "1.11.99.2",
|
||||
"version": "1.11.99.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/package-versions-deprecated.git",
|
||||
"reference": "c6522afe5540d5fc46675043d3ed5a45a740b27c"
|
||||
"reference": "fff576ac850c045158a250e7e27666e146e78d18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/c6522afe5540d5fc46675043d3ed5a45a740b27c",
|
||||
"reference": "c6522afe5540d5fc46675043d3ed5a45a740b27c",
|
||||
"url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/fff576ac850c045158a250e7e27666e146e78d18",
|
||||
"reference": "fff576ac850c045158a250e7e27666e146e78d18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -500,7 +504,7 @@
|
|||
"description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/package-versions-deprecated/issues",
|
||||
"source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.2"
|
||||
"source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -516,7 +520,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-05-24T07:46:03+00:00"
|
||||
"time": "2021-08-17T13:49:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
|
|
@ -1167,6 +1171,124 @@
|
|||
],
|
||||
"time": "2020-12-29T14:50:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "facade/flare-client-php",
|
||||
"version": "1.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facade/flare-client-php.git",
|
||||
"reference": "47b639dc02bcfdfc4ebb83de703856fa01e35f5f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facade/flare-client-php/zipball/47b639dc02bcfdfc4ebb83de703856fa01e35f5f",
|
||||
"reference": "47b639dc02bcfdfc4ebb83de703856fa01e35f5f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"facade/ignition-contracts": "~1.0",
|
||||
"illuminate/pipeline": "^5.5|^6.0|^7.0|^8.0",
|
||||
"php": "^7.1|^8.0",
|
||||
"symfony/http-foundation": "^3.3|^4.1|^5.0",
|
||||
"symfony/mime": "^3.4|^4.0|^5.1",
|
||||
"symfony/var-dumper": "^3.4|^4.0|^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.14",
|
||||
"phpunit/phpunit": "^7.5.16",
|
||||
"spatie/phpunit-snapshot-assertions": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facade\\FlareClient\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Send PHP errors to Flare",
|
||||
"homepage": "https://github.com/facade/flare-client-php",
|
||||
"keywords": [
|
||||
"exception",
|
||||
"facade",
|
||||
"flare",
|
||||
"reporting"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/facade/flare-client-php/issues",
|
||||
"source": "https://github.com/facade/flare-client-php/tree/1.8.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-05-31T19:23:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "facade/ignition-contracts",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facade/ignition-contracts.git",
|
||||
"reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
|
||||
"reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^v2.15.8",
|
||||
"phpunit/phpunit": "^9.3.11",
|
||||
"vimeo/psalm": "^3.17.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facade\\IgnitionContracts\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://flareapp.io",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Solution contracts for Ignition",
|
||||
"homepage": "https://github.com/facade/ignition-contracts",
|
||||
"keywords": [
|
||||
"contracts",
|
||||
"flare",
|
||||
"ignition"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/facade/ignition-contracts/issues",
|
||||
"source": "https://github.com/facade/ignition-contracts/tree/1.0.2"
|
||||
},
|
||||
"time": "2020-10-16T08:27:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fideloper/proxy",
|
||||
"version": "4.4.1",
|
||||
|
|
@ -1606,6 +1728,70 @@
|
|||
},
|
||||
"time": "2021-06-30T20:03:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "kwaadpepper/crud-policies",
|
||||
"version": "0.1.17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Kwaadpepper/crud-policies.git",
|
||||
"reference": "0cd52413f9ee2f95b2ebc2d2d4621cfc2a104e47"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Kwaadpepper/crud-policies/zipball/0cd52413f9ee2f95b2ebc2d2d4621cfc2a104e47",
|
||||
"reference": "0cd52413f9ee2f95b2ebc2d2d4621cfc2a104e47",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"facade/flare-client-php": "^1.8",
|
||||
"illuminate/support": "~7|~8",
|
||||
"kwaadpepper/enum": "^2.0",
|
||||
"laravel/framework": "~7|~8"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^6.13",
|
||||
"phpunit/phpunit": "~9.0",
|
||||
"slevomat/coding-standard": "^7.0",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Kwaadpepper\\CrudPolicies\\Providers\\CrudPoliciesServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Kwaadpepper\\CrudPolicies\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jérémy Munsch",
|
||||
"email": "github@jeremydev.ovh",
|
||||
"homepage": "https://jeremydev.ovh"
|
||||
}
|
||||
],
|
||||
"description": "Makes CRUD easy, make policies easy and everyone happy",
|
||||
"homepage": "https://github.com/kwaadpepper/crud-policies",
|
||||
"keywords": [
|
||||
"Scafolding",
|
||||
"crud",
|
||||
"laravel",
|
||||
"policies"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Kwaadpepper/crud-policies/issues",
|
||||
"source": "https://github.com/Kwaadpepper/crud-policies/tree/0.1.17"
|
||||
},
|
||||
"time": "2021-09-10T14:23:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "kwaadpepper/enum",
|
||||
"version": "2.0.0",
|
||||
|
|
@ -1708,16 +1894,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v8.53.1",
|
||||
"version": "v8.56.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "5df423c2790f32b26baee90518bb659572aa404f"
|
||||
"reference": "d700f336dc672dcbfe46db05d4e5fe9347b3a5b6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/5df423c2790f32b26baee90518bb659572aa404f",
|
||||
"reference": "5df423c2790f32b26baee90518bb659572aa404f",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/d700f336dc672dcbfe46db05d4e5fe9347b3a5b6",
|
||||
"reference": "d700f336dc672dcbfe46db05d4e5fe9347b3a5b6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1790,7 +1976,7 @@
|
|||
"illuminate/view": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"aws/aws-sdk-php": "^3.186.4",
|
||||
"aws/aws-sdk-php": "^3.189.0",
|
||||
"doctrine/dbal": "^2.6|^3.0",
|
||||
"filp/whoops": "^2.8",
|
||||
"guzzlehttp/guzzle": "^6.5.5|^7.0.1",
|
||||
|
|
@ -1803,7 +1989,7 @@
|
|||
"symfony/cache": "^5.1.4"
|
||||
},
|
||||
"suggest": {
|
||||
"aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.186.4).",
|
||||
"aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.189.0).",
|
||||
"brianium/paratest": "Required to run tests in parallel (^6.0).",
|
||||
"doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6|^3.0).",
|
||||
"ext-ftp": "Required to use the Flysystem FTP driver.",
|
||||
|
|
@ -1872,7 +2058,7 @@
|
|||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-08-05T14:04:08+00:00"
|
||||
"time": "2021-08-24T13:46:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/tinker",
|
||||
|
|
@ -2044,17 +2230,101 @@
|
|||
"time": "2021-07-17T17:13:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "1.1.4",
|
||||
"name": "league/csv",
|
||||
"version": "9.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "f3ad69181b8afed2c9edf7be5a2918144ff4ea32"
|
||||
"url": "https://github.com/thephpleague/csv.git",
|
||||
"reference": "0ec57e8264ec92565974ead0d1724cf1026e10c1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f3ad69181b8afed2c9edf7be5a2918144ff4ea32",
|
||||
"reference": "f3ad69181b8afed2c9edf7be5a2918144ff4ea32",
|
||||
"url": "https://api.github.com/repos/thephpleague/csv/zipball/0ec57e8264ec92565974ead0d1724cf1026e10c1",
|
||||
"reference": "0ec57e8264ec92565974ead0d1724cf1026e10c1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"ext-dom": "*",
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"phpstan/phpstan": "^0.12.0",
|
||||
"phpstan/phpstan-phpunit": "^0.12.0",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "Required to use the XMLConverter and or the HTMLConverter classes",
|
||||
"ext-iconv": "Needed to ease transcoding CSV using iconv stream filters"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "9.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Csv\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ignace Nyamagana Butera",
|
||||
"email": "nyamsprod@gmail.com",
|
||||
"homepage": "https://github.com/nyamsprod/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "CSV data manipulation made easy in PHP",
|
||||
"homepage": "http://csv.thephpleague.com",
|
||||
"keywords": [
|
||||
"convert",
|
||||
"csv",
|
||||
"export",
|
||||
"filter",
|
||||
"import",
|
||||
"read",
|
||||
"transform",
|
||||
"write"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://csv.thephpleague.com",
|
||||
"issues": "https://github.com/thephpleague/csv/issues",
|
||||
"rss": "https://github.com/thephpleague/csv/releases.atom",
|
||||
"source": "https://github.com/thephpleague/csv"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/nyamsprod",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-04-17T16:32:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "1.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "18634df356bfd4119fe3d6156bdb990c414c14ea"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/18634df356bfd4119fe3d6156bdb990c414c14ea",
|
||||
"reference": "18634df356bfd4119fe3d6156bdb990c414c14ea",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2127,7 +2397,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/flysystem/issues",
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/1.1.4"
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/1.1.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -2135,7 +2405,7 @@
|
|||
"type": "other"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-23T21:56:05+00:00"
|
||||
"time": "2021-08-17T13:49:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/mime-type-detection",
|
||||
|
|
@ -2291,16 +2561,16 @@
|
|||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "2.51.1",
|
||||
"version": "2.52.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922"
|
||||
"reference": "369c0e2737c56a0f39c946dd261855255a6fccbe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922",
|
||||
"reference": "8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/369c0e2737c56a0f39c946dd261855255a6fccbe",
|
||||
"reference": "369c0e2737c56a0f39c946dd261855255a6fccbe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2381,7 +2651,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-28T13:16:28+00:00"
|
||||
"time": "2021-08-14T19:10:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
|
|
@ -3181,16 +3451,16 @@
|
|||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
"version": "4.1.1",
|
||||
"version": "4.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ramsey/uuid.git",
|
||||
"reference": "cd4032040a750077205918c86049aa0f43d22947"
|
||||
"reference": "fe665a03df4f056aa65af552a96e1976df8c8dae"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ramsey/uuid/zipball/cd4032040a750077205918c86049aa0f43d22947",
|
||||
"reference": "cd4032040a750077205918c86049aa0f43d22947",
|
||||
"url": "https://api.github.com/repos/ramsey/uuid/zipball/fe665a03df4f056aa65af552a96e1976df8c8dae",
|
||||
"reference": "fe665a03df4f056aa65af552a96e1976df8c8dae",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3204,26 +3474,26 @@
|
|||
"rhumsaa/uuid": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/aspect-mock": "^3",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0",
|
||||
"captainhook/captainhook": "^5.10",
|
||||
"captainhook/plugin-composer": "^5.3",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||
"doctrine/annotations": "^1.8",
|
||||
"goaop/framework": "^2",
|
||||
"ergebnis/composer-normalize": "^2.15",
|
||||
"mockery/mockery": "^1.3",
|
||||
"moontoast/math": "^1.1",
|
||||
"paragonie/random-lib": "^2",
|
||||
"php-mock/php-mock": "^2.2",
|
||||
"php-mock/php-mock-mockery": "^1.3",
|
||||
"php-mock/php-mock-phpunit": "^2.5",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.1",
|
||||
"phpbench/phpbench": "^0.17.1",
|
||||
"phpbench/phpbench": "^1.0",
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpstan/phpstan-mockery": "^0.12",
|
||||
"phpstan/phpstan-phpunit": "^0.12",
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"psy/psysh": "^0.10.0",
|
||||
"slevomat/coding-standard": "^6.0",
|
||||
"phpunit/phpunit": "^8.5 || ^9",
|
||||
"slevomat/coding-standard": "^7.0",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"vimeo/psalm": "3.9.4"
|
||||
"vimeo/psalm": "^4.9"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.",
|
||||
|
|
@ -3236,7 +3506,10 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.x-dev"
|
||||
"dev-main": "4.x-dev"
|
||||
},
|
||||
"captainhook": {
|
||||
"force-install": true
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -3252,7 +3525,6 @@
|
|||
"MIT"
|
||||
],
|
||||
"description": "A PHP library for generating and working with universally unique identifiers (UUIDs).",
|
||||
"homepage": "https://github.com/ramsey/uuid",
|
||||
"keywords": [
|
||||
"guid",
|
||||
"identifier",
|
||||
|
|
@ -3260,16 +3532,19 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ramsey/uuid/issues",
|
||||
"rss": "https://github.com/ramsey/uuid/releases.atom",
|
||||
"source": "https://github.com/ramsey/uuid"
|
||||
"source": "https://github.com/ramsey/uuid/tree/4.2.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/ramsey",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/ramsey/uuid",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-08-18T17:17:46+00:00"
|
||||
"time": "2021-08-11T01:06:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rennokki/laravel-eloquent-query-cache",
|
||||
|
|
@ -3336,6 +3611,74 @@
|
|||
],
|
||||
"time": "2021-07-17T17:42:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-mix-preload",
|
||||
"version": "1.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/laravel-mix-preload.git",
|
||||
"reference": "b89dc366fa8a714ecb3d6af836db3c038795a3b6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/laravel-mix-preload/zipball/b89dc366fa8a714ecb3d6af836db3c038795a3b6",
|
||||
"reference": "b89dc366fa8a714ecb3d6af836db3c038795a3b6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^6.0|^7.0|^8.0",
|
||||
"php": "^7.2.5|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.0|^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Spatie\\MixPreload\\MixPreloadServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\MixPreload\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian De Deyne",
|
||||
"email": "sebastian@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Add preload and prefetch links based your Mix manifest",
|
||||
"homepage": "https://github.com/spatie/laravel-mix-preload",
|
||||
"keywords": [
|
||||
"laravel-mix-preload",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/laravel-mix-preload/issues",
|
||||
"source": "https://github.com/spatie/laravel-mix-preload/tree/1.2.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/spatie",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2021-01-04T08:01:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.2.7",
|
||||
|
|
@ -6072,83 +6415,18 @@
|
|||
],
|
||||
"time": "2020-11-10T18:47:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "facade/flare-client-php",
|
||||
"version": "1.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facade/flare-client-php.git",
|
||||
"reference": "47b639dc02bcfdfc4ebb83de703856fa01e35f5f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facade/flare-client-php/zipball/47b639dc02bcfdfc4ebb83de703856fa01e35f5f",
|
||||
"reference": "47b639dc02bcfdfc4ebb83de703856fa01e35f5f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"facade/ignition-contracts": "~1.0",
|
||||
"illuminate/pipeline": "^5.5|^6.0|^7.0|^8.0",
|
||||
"php": "^7.1|^8.0",
|
||||
"symfony/http-foundation": "^3.3|^4.1|^5.0",
|
||||
"symfony/mime": "^3.4|^4.0|^5.1",
|
||||
"symfony/var-dumper": "^3.4|^4.0|^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.14",
|
||||
"phpunit/phpunit": "^7.5.16",
|
||||
"spatie/phpunit-snapshot-assertions": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facade\\FlareClient\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Send PHP errors to Flare",
|
||||
"homepage": "https://github.com/facade/flare-client-php",
|
||||
"keywords": [
|
||||
"exception",
|
||||
"facade",
|
||||
"flare",
|
||||
"reporting"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/facade/flare-client-php/issues",
|
||||
"source": "https://github.com/facade/flare-client-php/tree/1.8.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-05-31T19:23:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "facade/ignition",
|
||||
"version": "2.11.2",
|
||||
"version": "2.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facade/ignition.git",
|
||||
"reference": "7c4e7a7da184cd00c7ce6eacc590200bb9672de7"
|
||||
"reference": "74dcc32a2895a126d1e5f2cd3bbab499cac66db1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facade/ignition/zipball/7c4e7a7da184cd00c7ce6eacc590200bb9672de7",
|
||||
"reference": "7c4e7a7da184cd00c7ce6eacc590200bb9672de7",
|
||||
"url": "https://api.github.com/repos/facade/ignition/zipball/74dcc32a2895a126d1e5f2cd3bbab499cac66db1",
|
||||
"reference": "74dcc32a2895a126d1e5f2cd3bbab499cac66db1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6211,60 +6489,7 @@
|
|||
"issues": "https://github.com/facade/ignition/issues",
|
||||
"source": "https://github.com/facade/ignition"
|
||||
},
|
||||
"time": "2021-07-20T14:01:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "facade/ignition-contracts",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facade/ignition-contracts.git",
|
||||
"reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
|
||||
"reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^v2.15.8",
|
||||
"phpunit/phpunit": "^9.3.11",
|
||||
"vimeo/psalm": "^3.17.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facade\\IgnitionContracts\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://flareapp.io",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Solution contracts for Ignition",
|
||||
"homepage": "https://github.com/facade/ignition-contracts",
|
||||
"keywords": [
|
||||
"contracts",
|
||||
"flare",
|
||||
"ignition"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/facade/ignition-contracts/issues",
|
||||
"source": "https://github.com/facade/ignition-contracts/tree/1.0.2"
|
||||
},
|
||||
"time": "2020-10-16T08:27:54+00:00"
|
||||
"time": "2021-08-24T09:53:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fakerphp/faker",
|
||||
|
|
@ -6585,16 +6810,16 @@
|
|||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
"version": "v5.6.0",
|
||||
"version": "v5.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nunomaduro/collision.git",
|
||||
"reference": "0122ac6b03c75279ef78d1c0ad49725dfc52a8d2"
|
||||
"reference": "0c3c393462eada1233513664e2d22bb9f69ca393"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/0122ac6b03c75279ef78d1c0ad49725dfc52a8d2",
|
||||
"reference": "0122ac6b03c75279ef78d1c0ad49725dfc52a8d2",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/0c3c393462eada1233513664e2d22bb9f69ca393",
|
||||
"reference": "0c3c393462eada1233513664e2d22bb9f69ca393",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6606,7 +6831,7 @@
|
|||
"require-dev": {
|
||||
"brianium/paratest": "^6.1",
|
||||
"fideloper/proxy": "^4.4.1",
|
||||
"friendsofphp/php-cs-fixer": "^2.17.3",
|
||||
"friendsofphp/php-cs-fixer": "^3.0",
|
||||
"fruitcake/laravel-cors": "^2.0.3",
|
||||
"laravel/framework": "^8.0 || ^9.0",
|
||||
"nunomaduro/larastan": "^0.6.2",
|
||||
|
|
@ -6669,7 +6894,7 @@
|
|||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-26T20:39:06+00:00"
|
||||
"time": "2021-08-13T14:23:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
|
|
@ -8567,16 +8792,16 @@
|
|||
},
|
||||
{
|
||||
"name": "slevomat/coding-standard",
|
||||
"version": "7.0.13",
|
||||
"version": "7.0.14",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slevomat/coding-standard.git",
|
||||
"reference": "122a9bf9a4a2195f74100f47dfb8375982f43cc9"
|
||||
"reference": "15b2b4630c148775debea8e412bc7e128d9868a3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slevomat/coding-standard/zipball/122a9bf9a4a2195f74100f47dfb8375982f43cc9",
|
||||
"reference": "122a9bf9a4a2195f74100f47dfb8375982f43cc9",
|
||||
"url": "https://api.github.com/repos/slevomat/coding-standard/zipball/15b2b4630c148775debea8e412bc7e128d9868a3",
|
||||
"reference": "15b2b4630c148775debea8e412bc7e128d9868a3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -8587,12 +8812,12 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"phing/phing": "2.16.4",
|
||||
"php-parallel-lint/php-parallel-lint": "1.3.0",
|
||||
"phpstan/phpstan": "0.12.93",
|
||||
"php-parallel-lint/php-parallel-lint": "1.3.1",
|
||||
"phpstan/phpstan": "0.12.96",
|
||||
"phpstan/phpstan-deprecation-rules": "0.12.6",
|
||||
"phpstan/phpstan-phpunit": "0.12.21",
|
||||
"phpstan/phpstan-strict-rules": "0.12.10",
|
||||
"phpunit/phpunit": "7.5.20|8.5.5|9.5.7"
|
||||
"phpstan/phpstan-phpunit": "0.12.22",
|
||||
"phpstan/phpstan-strict-rules": "0.12.11",
|
||||
"phpunit/phpunit": "7.5.20|8.5.5|9.5.8"
|
||||
},
|
||||
"type": "phpcodesniffer-standard",
|
||||
"extra": {
|
||||
|
|
@ -8612,7 +8837,7 @@
|
|||
"description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.",
|
||||
"support": {
|
||||
"issues": "https://github.com/slevomat/coding-standard/issues",
|
||||
"source": "https://github.com/slevomat/coding-standard/tree/7.0.13"
|
||||
"source": "https://github.com/slevomat/coding-standard/tree/7.0.14"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -8624,7 +8849,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-29T14:30:22+00:00"
|
||||
"time": "2021-08-26T12:17:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
|
|
|
|||
|
|
@ -227,7 +227,11 @@ return [
|
|||
'View' => Illuminate\Support\Facades\View::class,
|
||||
'Carbon' => Illuminate\Support\Carbon::class,
|
||||
'ArcadiaMailType' => App\Enums\ArcadiaMailType::class,
|
||||
'ArcadiaOrderType' => App\Enums\ArcadiaOrderType::class
|
||||
'ArcadiaOrderType' => App\Enums\ArcadiaOrderType::class,
|
||||
'CustomerExportType' => App\Enums\CustomerExportType::class,
|
||||
'Brand' => App\Models\Brand::class,
|
||||
'Customer' => App\Models\Customer::class,
|
||||
'Answer' => App\Models\Answer::class,
|
||||
],
|
||||
|
||||
];
|
||||
|
|
|
|||
37
package.json
37
package.json
|
|
@ -2,28 +2,27 @@
|
|||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "npm run development -- --watch",
|
||||
"watch-poll": "npm run watch -- --watch-poll",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"development": "mix",
|
||||
"watch": "mix watch",
|
||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "mix watch --hot",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
"production": "mix --production"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.19",
|
||||
"bootstrap": "^4.5.0",
|
||||
"cross-env": "^7.0",
|
||||
"jquery": "^3.2",
|
||||
"laravel-mix": "^5.0.1",
|
||||
"lodash": "^4.17.19",
|
||||
"popper.js": "^1.12",
|
||||
"resolve-url-loader": "^3.1.0",
|
||||
"sass-loader": "^8.0.2",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.21",
|
||||
"clean-webpack-plugin": "^4.0.0-alpha.0",
|
||||
"laravel-mix": "^6.0.6",
|
||||
"laravel-mix-polyfill": "^3.0.0",
|
||||
"moment": "^2.29.1",
|
||||
"sass": "^1.28.0",
|
||||
"vue": "^2.6.12"
|
||||
"postcss": "^8.1.14",
|
||||
"postcss-discard-comments": "^4.0.2",
|
||||
"resolve-url-loader": "^3.1.3",
|
||||
"sass": "^1.32.11",
|
||||
"sass-loader": "^11.0.1",
|
||||
"swiper": "^6.6.1",
|
||||
"vue": "^2.6.12",
|
||||
"vue-loader": "^15.9.6",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
/*!
|
||||
* Vue.js v2.6.12
|
||||
* (c) 2014-2020 Evan You
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Lodash <https://lodash.com/>
|
||||
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
||||
* Released under MIT license <https://lodash.com/license>
|
||||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||||
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||
*/
|
||||
|
||||
//! moment.js
|
||||
|
||||
//! moment.js locale configuration
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/app.js": "/js/app.js",
|
||||
"/css/app.css": "/css/app.css"
|
||||
"/js/preload-back.js": "/js/preload-back.js",
|
||||
"/css/preload-back.css": "/css/preload-back.css"
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
|
|
@ -1,101 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">Rechercher un opt-in</h1>
|
||||
<div class="spinner-border text-dark float-right" role="status" v-show="processing">
|
||||
<span class="sr-only">Chargement...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<label class="col-form-label col text-center">Marque :</label>
|
||||
<select v-model="selectedBrand" class="custom-select col">
|
||||
<option value="0" selected>Toutes les marques</option>
|
||||
<option v-for="item in brands" :key="item.id" :value="item.id">{{ item.name }}</option>
|
||||
</select>
|
||||
<label class="col-form-label col text-center">Votre recherche :</label>
|
||||
<input v-model="search" type="text" class="form-control col" placeholder="Entrer votre recherche ici" v-on:keyup.enter="enterSearch">
|
||||
</div>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Email</th>
|
||||
<th scope="col">Marque</th>
|
||||
<th scope="col">Date opt-in</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="emails">
|
||||
<tr v-for="item in datas" :key="item.id">
|
||||
<td>{{ item.email }}</td>
|
||||
<td>{{ brands.find(element => element.id === item.brand_id).name }}</td>
|
||||
<td>{{ item.created_at | formatDate }}</td>
|
||||
<td><a class="btn btn-sm btn-danger" @click="deleteOptin(item.id)">Supprimer</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
console.log('SearchOptin Component mounted.');
|
||||
this.brands = JSON.parse(this.dbbrands);
|
||||
},
|
||||
props: [
|
||||
'dbbrands',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
brands: [],
|
||||
datas: [],
|
||||
processing: false,
|
||||
search: '',
|
||||
selectedBrand: "0",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
enterSearch() {
|
||||
if (this.search.length < 1)
|
||||
return false;
|
||||
this.processing = true;
|
||||
let chaine = this.search;
|
||||
if (this.selectedBrand !== "0")
|
||||
chaine += '/' + this.selectedBrand;
|
||||
axios.get('/single-optins/filter/' + chaine)
|
||||
.then(
|
||||
(response) => {
|
||||
this.datas = response.data;
|
||||
this.processing = false;
|
||||
}
|
||||
)
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
this.processing = false;
|
||||
});
|
||||
},
|
||||
deleteOptin(id) {
|
||||
let r = confirm("Veuillez confirmer cette action en cliquant sur OK.");
|
||||
if (r === true) {
|
||||
axios.post('/single-optins/' + id + '/delete')
|
||||
.then(
|
||||
(response) => {
|
||||
if (response.data.status === 'OK'){
|
||||
this.datas = [];
|
||||
this.search = '';
|
||||
this.selectedBrand = "0";
|
||||
this.processing = false;
|
||||
alert("Suppression terminée.");
|
||||
}
|
||||
}
|
||||
)
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
this.processing = false;
|
||||
alert("Une erreur est survenue.");
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">Rechercher un client</h1>
|
||||
<div class="spinner-border text-dark float-right" role="status" v-show="processing">
|
||||
<span class="sr-only">Chargement...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<label class="col-form-label col text-center">Marque :</label>
|
||||
<select v-model="selectedBrand" class="custom-select col">
|
||||
<option value="0" selected>Toutes les marques</option>
|
||||
<option v-for="item in brands" :key="item.id" :value="item.id">{{ item.name }}</option>
|
||||
</select>
|
||||
<label class="col-form-label col text-center">Votre recherche :</label>
|
||||
<input v-model="search" type="text" class="form-control col" placeholder="Entrer votre recherche ici" v-on:keyup.enter="enterSearch">
|
||||
</div>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">CRM ID</th>
|
||||
<th scope="col">Email</th>
|
||||
<th scope="col">Nom</th>
|
||||
<th scope="col">Prénom</th>
|
||||
<th scope="col">Opt-In</th>
|
||||
<th scope="col">Marque</th>
|
||||
<th scope="col">Dernière connexion</th>
|
||||
<th scope="col">Voir</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="emails">
|
||||
<tr v-for="item in datas" :key="item.id">
|
||||
<td>{{ item.customer_id }}</td>
|
||||
<td>{{ item.email }}</td>
|
||||
<td>{{ item.lastname }}</td>
|
||||
<td>{{ item.firstname }}</td>
|
||||
<td>{{ item.opt_in === 1 ? "Oui" : "Non" }}</td>
|
||||
<td>{{ brands.find(element => element.id === item.brand_id).name }}</td>
|
||||
<td>{{ item.last_connection | formatDate }}</td>
|
||||
<td><a :href="'/customer/' + item.customer_id + '/' + item.brand_id" class="btn btn-sm btn-primary">Détail</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
console.log('SearchUser Component mounted.');
|
||||
this.brands = JSON.parse(this.dbbrands);
|
||||
},
|
||||
props: [
|
||||
'dbbrands',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
brands: [],
|
||||
datas: [],
|
||||
processing: false,
|
||||
search: '',
|
||||
selectedBrand: "0",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
enterSearch() {
|
||||
if (this.search.length < 1)
|
||||
return false;
|
||||
this.processing = true;
|
||||
let chaine = this.search;
|
||||
if (this.selectedBrand !== "0")
|
||||
chaine += '/' + this.selectedBrand;
|
||||
axios.get('/customers/filter/' + chaine)
|
||||
.then(
|
||||
(response) => {
|
||||
this.datas = response.data;
|
||||
this.processing = false;
|
||||
}
|
||||
)
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
this.processing = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
17
resources/js/app.js
vendored
17
resources/js/app.js
vendored
|
|
@ -1,17 +0,0 @@
|
|||
require('./bootstrap');
|
||||
import moment from 'moment';
|
||||
|
||||
window.Vue = require('vue');
|
||||
|
||||
Vue.filter('formatDate', function(value) {
|
||||
if (value) {
|
||||
return moment(String(value)).format('DD/MM/YYYY H:mm')
|
||||
}
|
||||
});
|
||||
|
||||
Vue.component('search-user', require('./Components/SearchUser.vue').default);
|
||||
Vue.component('search-optin', require('./Components/SearchOptin.vue').default);
|
||||
|
||||
const app = new Vue({
|
||||
el: '#app',
|
||||
});
|
||||
5
resources/js/back.js
vendored
Normal file
5
resources/js/back.js
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
require('./bootstrap');
|
||||
|
||||
require('./pages/customer.delete')
|
||||
require('./pages/service.index')
|
||||
require('./pages/single_optin.index')
|
||||
34
resources/js/pages/customer.delete.js
vendored
Normal file
34
resources/js/pages/customer.delete.js
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
let customerDelete = document.getElementById('customerDelete');
|
||||
|
||||
if (customerDelete) {
|
||||
customerDelete.addEventListener('submit', (e) => {
|
||||
let self = e.target
|
||||
e.preventDefault()
|
||||
Swal.fire({
|
||||
title: 'Supprimer ce client pour cette marque ?',
|
||||
text: 'Attention cette action est irréversible, si le client n\'appartient plus à aucune marque il sera complètement retiré des bases',
|
||||
icon: 'warning',
|
||||
confirmButtonText: 'Je comprends le danger et suis conscient de ce que je fait',
|
||||
showCancelButton: true,
|
||||
cancelButtonText: 'Annuler',
|
||||
confirmButtonColor: '#dc3545'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
Swal.fire({
|
||||
title: 'Attention au conséquences',
|
||||
html: 'La supression de ce compte dans la crm n\'entrainera pas ça supression dans MESBR ni dans le front cache DB (pour les sites WPCRM). <br><h3><b>Une fois le compte supprimé je ne pourrai plus récupérer le hashcode nécessaire pour effectuer ces opérations.</b></h3>',
|
||||
icon: 'info',
|
||||
confirmButtonText: 'Je comprends le danger et suis conscient que celà aura des conséquences',
|
||||
showCancelButton: true,
|
||||
cancelButtonText: 'Annuler',
|
||||
confirmButtonColor: '#dc3545'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
self.submit()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
36
resources/js/pages/service.index.js
vendored
Normal file
36
resources/js/pages/service.index.js
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
let genForms = document.getElementsByClassName('genToken');
|
||||
|
||||
if (genForms.length) {
|
||||
for (let form of genForms) {
|
||||
form.addEventListener('submit', (e) => {
|
||||
let self = e.target
|
||||
e.preventDefault()
|
||||
Swal.fire({
|
||||
title: 'Regénérer un token ?',
|
||||
text: 'Attention la regeneration empêchera le service de fonctionner tant que son token n\'aura pas été mis à jour',
|
||||
icon: 'warning',
|
||||
confirmButtonText: 'Je comprends le danger et suis conscient de ce que je fait',
|
||||
showCancelButton: true,
|
||||
cancelButtonText: 'Annuler',
|
||||
confirmButtonColor: '#dc3545'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
Swal.fire({
|
||||
title: 'Vous allez régénérer un token de service en production',
|
||||
html: '<h3><b>Je suis conscient que celà va avoir des implications et qu\'il me faudra mettre à jour le bearer token du service concerné dans son envirronement actuel</b></h3>',
|
||||
icon: 'info',
|
||||
confirmButtonText: 'Oui, feu patate !!',
|
||||
showCancelButton: true,
|
||||
cancelButtonText: 'Annuler',
|
||||
confirmButtonColor: '#dc3545'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
self.submit()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
10
resources/js/pages/single_optin.index.js
vendored
Normal file
10
resources/js/pages/single_optin.index.js
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
let brandSelect = document.getElementById('brandSelect');
|
||||
if (brandSelect) {
|
||||
brandSelect.addEventListener('change', function (e) {
|
||||
if (brandSelect.value !== '0') {
|
||||
const url = new URL(location.href);
|
||||
url.searchParams.set('brand', brandSelect.value);
|
||||
location.assign(url.search);
|
||||
}
|
||||
});
|
||||
}
|
||||
27
resources/lang/en/models.php
Normal file
27
resources/lang/en/models.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'classes' => [
|
||||
'services' => 'Services',
|
||||
'brands' => 'Brands',
|
||||
'brand' => 'Brand',
|
||||
'customers' => 'Customers',
|
||||
'questions' => 'Questions',
|
||||
'answers' => 'Answers',
|
||||
'singleoptins' => 'Single Opt-ins'
|
||||
],
|
||||
'common' => [
|
||||
'title' => 'Title',
|
||||
'name' => 'Name',
|
||||
'email' => 'Email',
|
||||
'content' => 'Content',
|
||||
'visibility' => 'Visibility',
|
||||
'published' => 'Published',
|
||||
'group' => 'Group',
|
||||
'default' => 'Default',
|
||||
'optinDate' => 'Date opt-in',
|
||||
'question' => 'Question',
|
||||
'answer' => 'Answer',
|
||||
'type' => 'Type'
|
||||
]
|
||||
];
|
||||
27
resources/lang/fr/models.php
Normal file
27
resources/lang/fr/models.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'classes' => [
|
||||
'services' => 'Services',
|
||||
'brands' => 'Marques',
|
||||
'brand' => 'Marque',
|
||||
'questions' => 'Questions',
|
||||
'answers' => 'Réponses',
|
||||
'customers' => 'Clients',
|
||||
'singleoptins' => 'Opt-ins uniques'
|
||||
],
|
||||
'common' => [
|
||||
'title' => 'Titre',
|
||||
'name' => 'Nom',
|
||||
'email' => 'E-mail',
|
||||
'content' => 'Contenu',
|
||||
'visibility' => 'Visibilitée',
|
||||
'published' => 'Publié',
|
||||
'group' => 'Groupe',
|
||||
'default' => 'Par défaut',
|
||||
'optinDate' => 'Date opt-in',
|
||||
'question' => 'Question',
|
||||
'type' => 'Type',
|
||||
'answer' => 'Réponse'
|
||||
]
|
||||
];
|
||||
103
resources/sass/_dashboard.scss
vendored
103
resources/sass/_dashboard.scss
vendored
|
|
@ -1,103 +0,0 @@
|
|||
body {
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
.feather {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sidebar
|
||||
*/
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100; /* Behind the navbar */
|
||||
padding: 48px 0 0; /* Height of navbar */
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.sidebar {
|
||||
top: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
position: relative;
|
||||
top: 0;
|
||||
height: calc(100vh - 48px);
|
||||
padding-top: .5rem;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||
}
|
||||
|
||||
@supports ((position: -webkit-sticky) or (position: sticky)) {
|
||||
.sidebar-sticky {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sidebar .nav-link .feather {
|
||||
margin-right: 4px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover .feather,
|
||||
.sidebar .nav-link.active .feather {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: .75rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/*
|
||||
* Navbar
|
||||
*/
|
||||
|
||||
.navbar-brand {
|
||||
padding-top: .75rem;
|
||||
padding-bottom: .75rem;
|
||||
font-size: 1rem;
|
||||
background-color: rgba(0, 0, 0, .25);
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
|
||||
.navbar .navbar-toggler {
|
||||
top: .25rem;
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
.navbar .form-control {
|
||||
padding: .75rem 1rem;
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.form-control-dark {
|
||||
color: #fff;
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
border-color: rgba(255, 255, 255, .1);
|
||||
}
|
||||
|
||||
.form-control-dark:focus {
|
||||
border-color: transparent;
|
||||
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
|
||||
}
|
||||
17
resources/sass/_layout.scss
vendored
Normal file
17
resources/sass/_layout.scss
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
.bodyFull {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
min-height: calc(100vh - #{$navBarHeight} - #{$footerHeight});
|
||||
}
|
||||
|
||||
#app {
|
||||
& > .navbar {
|
||||
height: $navBarHeight;
|
||||
}
|
||||
#footer {
|
||||
height: $footerHeight;
|
||||
padding: 0 !important;
|
||||
color: $body-bg;
|
||||
background-color: $footerBgColor;
|
||||
}
|
||||
}
|
||||
4
resources/sass/_variables.scss
vendored
4
resources/sass/_variables.scss
vendored
|
|
@ -22,3 +22,7 @@ $theme-colors: (
|
|||
"primary": #3176C4,
|
||||
"secondary": #E7374B
|
||||
);
|
||||
|
||||
$navBarHeight: 4rem;
|
||||
$footerHeight: 3rem;
|
||||
$footerBgColor: #161616;
|
||||
|
|
|
|||
10
resources/sass/app.scss
vendored
10
resources/sass/app.scss
vendored
|
|
@ -1,10 +0,0 @@
|
|||
// Fonts
|
||||
@import url('https://fonts.googleapis.com/css?family=Nunito');
|
||||
|
||||
// Variables
|
||||
@import 'variables';
|
||||
|
||||
// Bootstrap
|
||||
@import '~bootstrap/scss/bootstrap';
|
||||
|
||||
@import "dashboard";
|
||||
5
resources/sass/back.scss
vendored
Normal file
5
resources/sass/back.scss
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// Variables
|
||||
@import 'variables';
|
||||
@import 'layout';
|
||||
|
||||
@import "pages/login";
|
||||
54
resources/sass/pages/login.scss
vendored
Normal file
54
resources/sass/pages/login.scss
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
.bd-placeholder-img {
|
||||
font-size: 1.125rem;
|
||||
text-anchor: middle;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.bd-placeholder-img-lg {
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
}
|
||||
div.login {
|
||||
height: 100%;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
width: 100%;
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
.form-signin .checkbox {
|
||||
font-weight: 400;
|
||||
}
|
||||
.form-signin .form-control {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.form-signin .form-control:focus {
|
||||
z-index: 2;
|
||||
}
|
||||
.form-signin input[type="email"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
119
resources/views/answer/index.blade.php
Normal file
119
resources/views/answer/index.blade.php
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
@extends($viewLayout)
|
||||
|
||||
@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('crud-policies::crud.viewAny')))
|
||||
@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), trans(Str::plural(class_basename($modelClass)))))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
@include('crud-policies::crud.modules.breadcrumb', ['action' => CrudAction::viewAny()])
|
||||
@include('crud-policies::crud.modules.actionbar.bar', ['action' => CrudAction::viewAny()])
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col">
|
||||
{{ $models->links() }}
|
||||
</div>
|
||||
<div class="col">
|
||||
<form action="{{ url()->current() }}">
|
||||
<div class="input-group mb-3">
|
||||
<input type="search" name="search" class="form-control" value="{{ request()->search }}"/>
|
||||
<input type="text" name="sort_col" class="d-none" value="{{ request()->sort_col }}"/>
|
||||
<input type="text" name="sort_way" class="d-none" value="{{ request()->sort_way }}"/>
|
||||
<a class="btn btn-danger" href="{{ url()->current() }}">{{ __('crud-policies::crud.reset') }}</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('crud-policies::crud.search') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<h2>{{ request()->question->question }}</h2>
|
||||
</div>
|
||||
<table class="table text-center">
|
||||
<thead class="thead-dark">
|
||||
@include('crud-policies::crud.modules.sorter')
|
||||
</thead>
|
||||
<tbody>
|
||||
@if(count($models))
|
||||
|
||||
{{-- INIT QUERIES for OPTIMIZING --}}
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if($prop['type']->equals(CrudType::order()))
|
||||
@php ${"$modelTable$fieldName"} = $modelClass::max($fieldName); @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsTo()))
|
||||
@php try { $models->load(Str::singular((new $prop['belongsTo']())->getTable())); } catch(\Exception $e) {} @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsToMany()))
|
||||
@php $models->load("$fieldName"); @endphp
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- DISPLAY MODELS --}}
|
||||
@foreach($models as $model)
|
||||
<tr>
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if(in_array(CrudAction::viewAny(), $prop['actions']))
|
||||
@switch($prop['type'])
|
||||
@case(CrudType::belongsToMany() and $prop['belongsToMany'] === \App\Models\Project::class)
|
||||
<td>
|
||||
@foreach($model->{$fieldName} as $pSite)
|
||||
<a href="{{ CrudController::getRoutePrefixed($pSite->getTable().'.show', $pSite) }}">{{ $pSite->{$prop['belongsToManyLabel']} }}</a>
|
||||
@endforeach
|
||||
</td>
|
||||
@break
|
||||
@case(CrudType::password())
|
||||
{{-- Ignore --}}
|
||||
@break
|
||||
@default
|
||||
<td>@include('crud-policies::crud.printfield', [
|
||||
'action' => CrudAction::viewAny(),
|
||||
'field' => $model->{$fieldName},
|
||||
'props' => $prop,
|
||||
"$modelTable$fieldName" => ${"$modelTable$fieldName"} ?? null
|
||||
])</td>
|
||||
@endswitch
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- MODEL ACTIONS --}}
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="{{ Str::plural(__('crud-policies::crud.action')) }}">
|
||||
@can('view', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.show", $model) }}" class="btn btn-sm btn-primary">{{ __('crud-policies::crud.view') }}</a>
|
||||
@endcan
|
||||
@can('update', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.edit", $model) }}" class="btn btn-sm btn-info">{{ __('crud-policies::crud.edit') }}</a>
|
||||
@endcan
|
||||
@can('delete', $model)
|
||||
<form action="{{ CrudController::getRoutePrefixed("$modelTable.destroy", $model) }}" method="POST" onsubmit="__CRUD.confirmDelete(event)">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-danger">{{ __('crud-policies::crud.delete') }}</button>
|
||||
</form>
|
||||
@endcan
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="{{ count($modelClass::getEditableProperties()) }}">
|
||||
{{ __('crud-policies::crud.nothingtoshow') }}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $models->links() }}
|
||||
</div>
|
||||
<div class="row justify-content-center mt-5 mb-5">
|
||||
<div class="col-1">{{ $models->links() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
158
resources/views/brand/index.blade.php
Normal file
158
resources/views/brand/index.blade.php
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
@extends($viewLayout)
|
||||
|
||||
@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('crud-policies::crud.viewAny')))
|
||||
@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), trans(Str::plural(class_basename($modelClass)))))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
@include('crud-policies::crud.modules.breadcrumb', ['action' => CrudAction::viewAny()])
|
||||
@include('crud-policies::crud.modules.actionbar.bar', ['action' => CrudAction::viewAny()])
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-end">
|
||||
<div class="col-6">
|
||||
<form action="{{ url()->current() }}">
|
||||
<div class="input-group mb-3">
|
||||
<input type="search" name="search" class="form-control" value="{{ request()->search }}" placeholder="Recherche.."/>
|
||||
<input type="text" name="sort_col" class="d-none" value="{{ request()->sort_col }}"/>
|
||||
<input type="text" name="sort_way" class="d-none" value="{{ request()->sort_way }}"/>
|
||||
@if(request()->brand)
|
||||
<input type="hidden" name="brand" class="d-none" value="{{ request()->brand }}"/>
|
||||
@endif
|
||||
<a class="btn btn-danger" href="{{ url()->current() }}">{{ __('crud-policies::crud.reset') }}</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('crud-policies::crud.search') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table text-center">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
@foreach ($modelClass::getEditableProperties() as $colname => $prop)
|
||||
@if(in_array(CrudAction::viewAny(), $prop['actions']))
|
||||
@switch($prop['type'])
|
||||
@case(CrudType::password())
|
||||
{{-- Ignore --}}
|
||||
@break
|
||||
@default
|
||||
<th scope="col">
|
||||
{{ $prop['label'] }}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc']) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc']) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
@endswitch
|
||||
@endif
|
||||
@endforeach
|
||||
<th scope="col">
|
||||
{{ __('Nombre de comptes')}}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{{ __('Nombre d\'optins')}}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{{ __('Date d\'ajout en base')}}
|
||||
</th>
|
||||
<th scope="col">
|
||||
@if(session("crud.$modelTable.sort_way") and session("crud.$modelTable.sort_col"))
|
||||
<a href="{{ request()->fullUrlWithQuery(['rst' => 'true']) }}" class="btn btn-small btn-danger">⌫</a>
|
||||
@endif
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if(count($models))
|
||||
|
||||
{{-- INIT QUERIES for OPTIMIZING --}}
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if($prop['type']->equals(CrudType::order()))
|
||||
@php ${"$modelTable$fieldName"} = $modelClass::max($fieldName); @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsTo()))
|
||||
@php try { $models->load(Str::singular((new $prop['belongsTo']())->getTable())); } catch(\Exception $e) {} @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsToMany()))
|
||||
@php $models->load("$fieldName"); @endphp
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- DISPLAY MODELS --}}
|
||||
@foreach($models as $model)
|
||||
<tr>
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if(in_array(CrudAction::viewAny(), $prop['actions']))
|
||||
@switch($prop['type'])
|
||||
@case(CrudType::belongsToMany() and $prop['belongsToMany'] === \App\Models\Project::class)
|
||||
<td>
|
||||
@foreach($model->{$fieldName} as $pSite)
|
||||
<a href="{{ CrudController::getRoutePrefixed($pSite->getTable().'.show', $pSite) }}">{{ $pSite->{$prop['belongsToManyLabel']} }}</a>
|
||||
@endforeach
|
||||
</td>
|
||||
@break
|
||||
@case(CrudType::password())
|
||||
{{-- Ignore --}}
|
||||
@break
|
||||
@default
|
||||
<td>@include('crud-policies::crud.printfield', [
|
||||
'action' => CrudAction::viewAny(),
|
||||
'field' => $model->{$fieldName},
|
||||
'props' => $prop,
|
||||
"$modelTable$fieldName" => ${"$modelTable$fieldName"} ?? null
|
||||
])</td>
|
||||
@endswitch
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- INFO COLS --}}
|
||||
<td>{{ $model->getAccountsAttribute() }}</td>
|
||||
<td>{{ $model->getTotalOptinsAttribute() }}</td>
|
||||
<td>{{ $model->created_at->format('m/d/Y à H:i') }}</td>
|
||||
|
||||
{{-- MODEL ACTIONS --}}
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="{{ Str::plural(__('crud-policies::crud.action')) }}">
|
||||
@can('view', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.show", $model) }}" class="btn btn-sm btn-primary">{{ __('crud-policies::crud.view') }}</a>
|
||||
@endcan
|
||||
@can('update', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.edit", $model) }}" class="btn btn-sm btn-info">{{ __('crud-policies::crud.edit') }}</a>
|
||||
@endcan
|
||||
@can('delete', $model)
|
||||
<form action="{{ CrudController::getRoutePrefixed("$modelTable.destroy", $model) }}" method="POST" onsubmit="__CRUD.confirmDelete(event)">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-danger">{{ __('crud-policies::crud.delete') }}</button>
|
||||
</form>
|
||||
@endcan
|
||||
@can('viewAny', \App\Models\Log::class)
|
||||
<a href="{{ CrudController::getRoutePrefixed("sites.logs.index", $model) }}" class="btn btn-sm btn-dark">{{ __('Journaux') }}</a>
|
||||
@endcan
|
||||
@can('viewAny', \App\Models\File::class)
|
||||
<a href="{{ CrudController::getRoutePrefixed("sites.files.index", $model) }}" class="btn btn-sm btn-dark">{{ __('Fichiers') }}</a>
|
||||
@endcan
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="{{ count($modelClass::getEditableProperties()) }}">
|
||||
{{ __('crud-policies::crud.nothingtoshow') }}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $models->links() }}
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h2>{{ __('Gestion des marques') }} <small class="text-muted">{{ __('Liste') }}</small></h2>
|
||||
<a href="{{ route('manage-brand') }}" class="btn btn-sm btn-primary float-right">{{ __('Ajouter') }}</a>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>{{ __('Nom de la marque') }}</th>
|
||||
<th>{{ __('Nombre de comptes') }}</th>
|
||||
<th>{{ __('Nombre d\'optins') }}</th>
|
||||
<th>{{ __('Date d\'ajout en base') }}</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($brands as $brand)
|
||||
<tr>
|
||||
<td>{{ $brand->name }}</td>
|
||||
<td>{{ $brand->accounts }}</td>
|
||||
<td>{{ $brand->total_optins }}</td>
|
||||
<td>{{ Carbon::parse($brand->created_at)->format('d/m/Y à H:i') }}</td>
|
||||
<td><a href="{{ route('manage-brand', $brand) }}" class="btn btn-sm btn-success">{{ __('Modifier') }}</a></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endsection
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h2>{{ __('Gestion des marques') }} <small class="text-muted">{{ __('Gestion') }}</small></h2>
|
||||
@if ($errors->any())
|
||||
<ul class="text-danger text-center">
|
||||
@foreach(session('errors')->all(':message') as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
@if (session('success'))
|
||||
<span class="text-success text-center">{!! session('success') !!}</span>
|
||||
@endif
|
||||
<a href="{{ route('brands') }}" class="btn btn-sm btn-primary float-right">{{ __('Retour') }}</a>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<form action="{{ route('manage-brand', $brand) }}" method="POST">
|
||||
@csrf
|
||||
<div class="form-group form-row">
|
||||
<label class="col-form-label col">{{ __('Nom de la marque') }}</label>
|
||||
<input type="text" name="name" class="form-control col" value="{{ $brand->name ?? null }}">
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<input type="submit" class="btn btn-success" value="{{ __('Enregistrer') }}">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
68
resources/views/customer/export.blade.php
Normal file
68
resources/views/customer/export.blade.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', sprintf('%s - %s', __('Newsletter Contacts'), __('Export')))
|
||||
@section('description', sprintf('%s - %s', __('Newsletter Contacts'), __('Export')))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
<nav aria-label="breadcrumb" class="d-inline">
|
||||
<ol class="breadcrumb d-inline-flex">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{{ route('customers.index') }}">{{ __('models.classes.customers') }}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{{__('Exporter un liste de client pour une newsletter') }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mt-5 mb-5" action="{{ route('customers.exportSubmit') }}" method="POST">
|
||||
@csrf
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6 col-md-10 col-12 mb-5">
|
||||
<h1>{{ __('Exporter un liste de client pour une newsletter') }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6 col-md-10 col-12">
|
||||
<fieldset>
|
||||
<legend>{{ __('La marque concernée') }}</legend>
|
||||
<div class="input-group mb-3">
|
||||
<label class="input-group-text" for="exportBrand">{{ __('Les client de la marque') }}</label>
|
||||
<select class="form-select" id="exportBrand" name="brand" required>
|
||||
<option selected value="">{{ __('Choissez une marque') }}</option>
|
||||
@foreach($brands as $i => $brand)
|
||||
<option value="{{ $brand->id }}">{{ $brand->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6 col-md-10 col-12">
|
||||
<fieldset>
|
||||
<legend>{{ __('Type d\'export') }}</legend>
|
||||
@foreach(CustomerExportType::toArray() as $i => $exportType)
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="export_type" id="exportType{{ $i }}" value="{{ $exportType->value }}" required>
|
||||
<label class="form-check-label" for="exportType{{ $i }}">
|
||||
{{ $exportType->label }}
|
||||
</label>
|
||||
</div>
|
||||
@endforeach
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center mt-4">
|
||||
<div class="col-lg-6 col-md-10 col-12">
|
||||
<button type="submit" class="btn btn-primary">{{ __('Exporter') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
73
resources/views/customer/index-tableHeaders.blade.php
Normal file
73
resources/views/customer/index-tableHeaders.blade.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<th scope="col">
|
||||
@php $colname = 'customers.email' @endphp
|
||||
{{ __('Email')}}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc', 'rst' => null]) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc', 'rst' => null]) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
<th scope="col">
|
||||
@php $colname = 'customer_infos.lastname' @endphp
|
||||
{{ __('Nom')}}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc', 'rst' => null]) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc', 'rst' => null]) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
<th scope="col">
|
||||
@php $colname = 'customer_infos.firstname' @endphp
|
||||
{{ __('Prénom')}}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc', 'rst' => null]) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc', 'rst' => null]) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
<th scope="col">
|
||||
@php $colname = 'customer_infos.opt_in' @endphp
|
||||
{{ __('Opt-In')}}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc', 'rst' => null]) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc', 'rst' => null]) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
<th scope="col">
|
||||
@php $colname = 'brands.name' @endphp
|
||||
{{ __('Marque')}}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc', 'rst' => null]) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc', 'rst' => null]) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
<th scope="col">
|
||||
@php $colname = 'customer_logins.status' @endphp
|
||||
{{ __('Activé ?')}}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc', 'rst' => null]) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc', 'rst' => null]) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
<th scope="col">
|
||||
@php $colname = 'customer_logins.last_connection' @endphp
|
||||
{{ __('Dernière connexion')}}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc', 'rst' => null]) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc', 'rst' => null]) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
<th scope="col">
|
||||
{{ __('Voir')}}
|
||||
</th>
|
||||
108
resources/views/customer/index.blade.php
Normal file
108
resources/views/customer/index.blade.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', sprintf('%s - %s', Str::ucfirst(Str::plural(trans('models.classes.customers'))), __('crud-policies::crud.viewAny')))
|
||||
@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), Str::ucfirst(Str::plural(trans('models.classes.customers')))))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
@include('crud-policies::crud.modules.breadcrumb', ['action' => CrudAction::viewAny()])
|
||||
@include('crud-policies::crud.modules.actionbar.bar', ['action' => CrudAction::viewAny()])
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col">
|
||||
<form action="{{ url()->current() }}">
|
||||
<div class="input-group mb-3">
|
||||
<label class="input-group-text" for="brandSelect">{{ __('Filter par Marque') }}</label>
|
||||
<select class="form-select" id="brandSelect">
|
||||
<option value="0" @if(!request()->brand) selected @endif>{{ __('Sélectionnez une marque..') }}</option>
|
||||
@foreach(Brand::all() as $brand)
|
||||
<option value="{{ $brand->id }}" @if(request()->brand == "$brand->id" or Session::get("crud.$modelTable.brand") == $brand->id) selected @endif>{{ $brand->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label class="input-group-text bg-warning" for="searchField">🔍🠚</label>
|
||||
<input type="search" id="searchField" name="search" class="form-control" value="{{ request()->search ?? Session::get("crud.$modelTable.search") }}" placeholder="Recherche.."/>
|
||||
<input type="text" name="sort_col" class="d-none" value="{{ request()->sort_col }}"/>
|
||||
<input type="text" name="sort_way" class="d-none" value="{{ request()->sort_way }}"/>
|
||||
@if(request()->brand)
|
||||
<input type="hidden" name="brand" class="d-none" value="{{ request()->brand }}"/>
|
||||
@endif
|
||||
<a class="btn btn-danger" href="{{ url()->current() }}">{{ __('crud-policies::crud.reset') }}</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('crud-policies::crud.search') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{ $customers->appends(Request::except('rst'))->links() }}
|
||||
<table class="table text-center">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
@include('customer.index-tableHeaders')
|
||||
<th scope="col">
|
||||
@if(session("crud.$modelTable.sort_way") and session("crud.$modelTable.sort_col"))
|
||||
<a href="{{ request()->fullUrlWithQuery(['rst' => 'true', 'sort_col' => null, 'sort_way' => null]) }}" class="btn btn-small btn-danger">⌫</a>
|
||||
@endif
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if(count($customers))
|
||||
|
||||
{{-- DISPLAY MODELS --}}
|
||||
@foreach($customers as $customerInfo)
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
{{ $customerInfo->customer->email }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $customerInfo->firstname }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $customerInfo->lastname }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $customerInfo->opt_in ? 'Oui' :'Non' }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $customerInfo->brand->name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $customerInfo->status ? 'Oui' :'Non' }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $customerInfo->last_connection }}
|
||||
</td>
|
||||
|
||||
{{-- MODEL ACTIONS --}}
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="{{ Str::plural(__('crud-policies::crud.action')) }}">
|
||||
@can('view', $customerInfo->customer)
|
||||
<a href="{{ CrudController::getRoutePrefixed("customers.show", [
|
||||
'customer' => $customerInfo->customer_id,
|
||||
'brand' => $customerInfo->brand_id
|
||||
]) }}" class="btn btn-sm btn-primary">{{ __('crud-policies::crud.view') }}</a>
|
||||
@endcan
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
{{ __('crud-policies::crud.nothingtoshow') }}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $customers->appends(Request::except('rst'))->links() }}
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
113
resources/views/customer/show.blade.php
Normal file
113
resources/views/customer/show.blade.php
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('crud-policies::crud.viewAny')))
|
||||
@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), trans(Str::plural(class_basename($modelClass)))))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
<nav aria-label="breadcrumb" class="d-inline">
|
||||
<ol class="breadcrumb d-inline-flex">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{{ route('customers.index') }}">{{ __('models.classes.customers') }}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{{__('Liste') }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col">
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">{{ __('Informations du client') }} {{ $customerInfos->firstname }} {{ $customerInfos->lastname }} - {{ Str::singular(__('models.classes.brands')) }} {{ $customerInfos->brand->name }}</h1>
|
||||
<a href="{{ route('customers.index') }}" class="btn btn-sm btn-primary float-right">Retour</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-sm table-bordered table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="w-50"><b>{{ __('Email') }}</b></td>
|
||||
<td class="w-50">{{ $customerInfos->customer->email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Prénom</b></td>
|
||||
<td>{{ $customerInfos->firstname }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Nom</b></td>
|
||||
<td>{{ $customerInfos->lastname }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date de naissance</b></td>
|
||||
<td>{{ \Carbon\Carbon::parse($customerInfos->birth_date)->format('d/m/Y') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Téléphone</b></td>
|
||||
<td>{{ $customerInfos->phone }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Adresse</b></td>
|
||||
<td>{{ $customerInfos->address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Adresse complémentaire</b></td>
|
||||
<td>{{ $customerInfos->address2 }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Pays</b></td>
|
||||
<td>{{ $customerInfos->country }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Ville</b></td>
|
||||
<td>{{ $customerInfos->city }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Code postal</b></td>
|
||||
<td>{{ $customerInfos->postcode }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Abonné à la newsletter</b></td>
|
||||
<td>{{ $customerInfos->opt_in === 1 ? "Oui" : "Non" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date de la dernière modification de l'abonnement</b></td>
|
||||
@if($customerInfos->customer->optInHistory()->orderBy('created_at', 'DESC')->exists())
|
||||
<td>{{ \Carbon\Carbon::parse($customerInfos->customer->optInHistory()->orderBy('created_at', 'DESC')->first()->created_at)->format('d/m/Y à H:i') }}</td>
|
||||
@else
|
||||
<td></td>
|
||||
@endif
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Dernière connexion</b></td>
|
||||
<td>{{ \Carbon\Carbon::parse($customerLogin->last_connection)->format('d/m/Y à H:i') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Status du compte</b></td>
|
||||
<td>{{ $customerLogin->status === 1 ? "Activé" : "Non activé" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Hashcode</b></td>
|
||||
<td>{{ $customerInfos->hashcode }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date de création</b></td>
|
||||
<td>{{ \Carbon\Carbon::parse($customerInfos->created_at)->format('d/m/Y à H:i') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date de modification</b></td>
|
||||
<td>{{ \Carbon\Carbon::parse($customerInfos->updated_at)->format('d/m/Y à H:i') }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<form id="customerDelete" action="{{ route('customers.delete', ['customer' => $customerInfos->customer_id, 'brand' => $customerInfos->brand_id]) }}" method="POST">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<input type="submit" value="{{ __('Supprimer') }}" class="btn btn-sm btn-danger">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
@if (session()->has('success'))
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3">
|
||||
<div class="alert alert-success">
|
||||
<p>{{ session()->get('success') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@if ($errors->any())
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3">
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<search-user dbbrands='@json($brands)'></search-user>
|
||||
@endsection
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">Informations du client {{ $customerInfos->firstname }} {{ $customerInfos->lastname }} - Marque {{ $customerInfos->brand->name }}</h1>
|
||||
<a href="{{ route('customers') }}" class="btn btn-sm btn-primary float-right">Retour</a>
|
||||
</div>
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<table class="table table-sm table-bordered table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="w-50"><b>Email</b></td>
|
||||
<td class="w-50">{{ $customerInfos->customer->email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Prénom</b></td>
|
||||
<td>{{ $customerInfos->firstname }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Nom</b></td>
|
||||
<td>{{ $customerInfos->lastname }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date de naissance</b></td>
|
||||
<td>{{ \Carbon\Carbon::parse($customerInfos->birth_date)->format('d/m/Y') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Téléphone</b></td>
|
||||
<td>{{ $customerInfos->phone }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Adresse</b></td>
|
||||
<td>{{ $customerInfos->address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Adresse complémentaire</b></td>
|
||||
<td>{{ $customerInfos->address2 }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Pays</b></td>
|
||||
<td>{{ $customerInfos->country }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Ville</b></td>
|
||||
<td>{{ $customerInfos->city }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Code postal</b></td>
|
||||
<td>{{ $customerInfos->postcode }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Abonné à la newsletter</b></td>
|
||||
<td>{{ $customerInfos->opt_in === 1 ? "Oui" : "Non" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date de la dernière modification de l'abonnement</b></td>
|
||||
@if($customerInfos->customer->optInHistory()->orderBy('created_at', 'DESC')->exists())
|
||||
<td>{{ \Carbon\Carbon::parse($customerInfos->customer->optInHistory()->orderBy('created_at', 'DESC')->first()->created_at)->format('d/m/Y à H:i') }}</td>
|
||||
@else
|
||||
<td></td>
|
||||
@endif
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Dernière connexion</b></td>
|
||||
<td>{{ \Carbon\Carbon::parse($customerLogin->last_connection)->format('d/m/Y à H:i') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Status du compte</b></td>
|
||||
<td>{{ $customerLogin->status === 1 ? "Activé" : "Non activé" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Hashcode</b></td>
|
||||
<td>{{ $customerInfos->hashcode }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date de création</b></td>
|
||||
<td>{{ \Carbon\Carbon::parse($customerInfos->created_at)->format('d/m/Y à H:i') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date de modification</b></td>
|
||||
<td>{{ \Carbon\Carbon::parse($customerInfos->updated_at)->format('d/m/Y à H:i') }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<form action="{{ route('customers.delete', ['customer' => $customerInfos->customer_id, 'brand' => $customerInfos->brand->id]) }}" method="POST" onsubmit="return confirm('{{ __('Êtes-vous sûr de vouloir supprimer cet utilisateur ?') }}');">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<input type="submit" value="{{ __('Supprimer') }}" class="btn btn-sm btn-danger">
|
||||
</form>
|
||||
@endsection
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Tableau de bord</title>
|
||||
|
||||
<script src="https://cdn.ckeditor.com/ckeditor5/23.0.0/classic/ckeditor.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
|
||||
<a class="navbar-brand col-md-3 col-lg-2 mr-0 px-3" href="#">{{ config('app.name') }}</a>
|
||||
<button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-toggle="collapse" data-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
||||
<div class="sidebar-sticky pt-3">
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||
<span>CLIENTS</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item"><a class="nav-link" href="{{route('customers')}}">Rechercher un client</a></li>
|
||||
</ul>
|
||||
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||
<span>OPT-INS UNIQUES</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item"><a class="nav-link" href="{{route('single-optins')}}">Rechercher un opt-in</a></li>
|
||||
</ul>
|
||||
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||
<span>MARQUES</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item"><a class="nav-link" href="{{route('brands')}}">Gestion des marques</a></li>
|
||||
</ul>
|
||||
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||
<span>SERVICES</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item"><a class="nav-link" href="{{route('services')}}">Gestion des services</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav flex-column mb-2" style="position: absolute; bottom: 5px;">
|
||||
<li class="nav-item"><a class="nav-link" href="{{route('logout')}}">Se déconnecter</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
|
||||
@yield('content')
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/app.js"></script>
|
||||
@yield('scripts')
|
||||
</body>
|
||||
</html>
|
||||
35
resources/views/layouts/app.blade.php
Normal file
35
resources/views/layouts/app.blade.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<!doctype html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
@include('layouts.backend.head')
|
||||
@stack('styles')
|
||||
@crudPoliciesCSS()
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
@include('layouts.backend.navbar')
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
@if(isset($modelsClasses))
|
||||
@include('layouts.backend.sidenav')
|
||||
<main role="main" class="col-md-9 mt-5 mb-5 ml-sm-auto col-lg-10 px-md-4 bodyFull">
|
||||
@else
|
||||
<main role="main" class="mt-5 mb-5 bodyFull">
|
||||
@endif
|
||||
@yield('content')
|
||||
</main>
|
||||
</div>
|
||||
<div class="row">
|
||||
@include('layouts.backend.footer')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stack('scriptsConstants')
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha256-edRDsV9ULIqKzKjpN/KjyQ7Lp4vUn9usbJuHjH8Sk+k=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.0.16/dist/sweetalert2.all.min.js" integrity="sha256-551HBsteMvKOSqjUXSmRy/EOF0bBNbWB96b5L3Deh8A=" crossorigin="anonymous"></script>
|
||||
<script src="{{ asset('js/preload-back.js') }}"></script>
|
||||
@crudPoliciesJS()
|
||||
@stack('scripts')
|
||||
</body>
|
||||
</html>
|
||||
10
resources/views/layouts/backend/footer.blade.php
Normal file
10
resources/views/layouts/backend/footer.blade.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<footer id="footer" class="text-center text-lg-start">
|
||||
<div class="text-center p-2" style="background-color: rgba(0, 0, 0, 0.05);">
|
||||
<span class="text-reset">{{ $license }}</span>
|
||||
-
|
||||
<span class="text-reset">{{ $name }} - {{ $version }}</span>
|
||||
-
|
||||
<span class="text-reset fw-bold">LDC Web Services</span>
|
||||
© {{ date('Y') }}
|
||||
</div>
|
||||
</footer>
|
||||
32
resources/views/layouts/backend/head.blade.php
Normal file
32
resources/views/layouts/backend/head.blade.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
|
||||
<title>{{ config('app.name') }}@hasSection('title') - @yield('title')@endif</title>
|
||||
<meta name="description" content="@yield('description')">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
|
||||
@hasSection('canonical')
|
||||
<link rel="canonical" href="@yield('canonical')" />
|
||||
@else
|
||||
<link rel="canonical" href="{{ url()->current() }}" />
|
||||
@endif
|
||||
|
||||
<!-- META INDEX, FOLLOW -->
|
||||
@hasSection('metaIndex')
|
||||
<meta name="robots" content="@yield('metaIndex')">
|
||||
@else
|
||||
<meta name="robots" content="index, follow">
|
||||
@endif
|
||||
|
||||
<!-- Favicon -->
|
||||
{{-- <link rel="icon" href="{{ asset('assets/images/favicon.png') }}" type="image/png">
|
||||
<link rel="icon" sizes="16x16" href="{{ asset('assets/images/LG-favicons_16x16.png') }}" type="image/png">
|
||||
<link rel="icon" sizes="32x32" href="{{ asset('assets/images/LG-favicons_32x32.png') }}" type="image/png">
|
||||
<link rel="icon" sizes="48x48" href="{{ asset('assets/images/LG-favicons_48x48.png') }}" type="image/png"> --}}
|
||||
|
||||
@preload('mix-manifest.json')
|
||||
|
||||
<!-- STYLES -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" integrity="sha256-hHKA3d/HttC8OW3Sl093W8DoZudhHJDj++kZYo6MLzA=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11.0.16/dist/sweetalert2.min.css" integrity="sha256-qpXwccFYncH5gTqXFe9EXZ8QeDw1Re68bbNVfFZzIzg=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{{ asset('css/preload-back.css') }}">
|
||||
15
resources/views/layouts/backend/navbar.blade.php
Normal file
15
resources/views/layouts/backend/navbar.blade.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="{{ route('home') }}">{{ config('app.name') }}</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarScroll" aria-controls="navbarScroll" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarScroll">
|
||||
<ul class="navbar-nav ms-auto my-2 my-lg-0 navbar-nav-scroll " style="--bs-scroll-height: 100px;">
|
||||
@auth()
|
||||
<li class="nav-item"><span class="nav-link text-success">{{ auth()->user()->name }}</span></li>
|
||||
@endauth
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
70
resources/views/layouts/backend/sidenav.blade.php
Normal file
70
resources/views/layouts/backend/sidenav.blade.php
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<nav id="sidebarMenu" class="col-md-3 col-lg-2 min-height-100vh d-md-block bg-light sidebar collapse">
|
||||
<div class="sidebar-sticky pt-3 d-flex flex-column justify-content-between align-items-center">
|
||||
<div class="col-12 mt-4">
|
||||
<h6 class="sidebar-heading px-3 mb-1 text-muted">
|
||||
<span>{{ __(sprintf('models.classes.%s', strtolower(Str::plural(class_basename(Customer::class))))) }}</span>
|
||||
</h6>
|
||||
@php
|
||||
$crudModel = Customer::class;
|
||||
$crudModel = new $crudModel();
|
||||
@endphp
|
||||
<ul class="nav flex-column mb-2">
|
||||
@can('viewAny', $crudModel)
|
||||
<li class="nav-item"><a class="nav-link" href="{{ route(sprintf('%s%s.index', $prefix ?? '', $crudModel->getTable())) }}">{{ __('Liste') }}</a></li>
|
||||
@endcan
|
||||
@can('create', $crudModel)
|
||||
<li class="nav-item"><a class="nav-link" href="{{ route(sprintf('%s%s.create', $prefix ?? '', $crudModel->getTable())) }}">{{ __('Ajouter') }}</a></li>
|
||||
@endcan
|
||||
</ul>
|
||||
<hr>
|
||||
@foreach($modelsClasses as $crudModel)
|
||||
@php if($crudModel === \App\Models\Answer::class) continue; @endphp
|
||||
@php if($crudModel === \App\Models\Customer::class) continue; @endphp
|
||||
@if(
|
||||
auth()->user()->can('viewAny', $crudModel) or
|
||||
auth()->user()->can('create', $crudModel)
|
||||
)
|
||||
<h6 class="sidebar-heading px-3 mb-1 text-muted">
|
||||
<span>{{ __(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($crudModel))))) }}</span>
|
||||
</h6>
|
||||
@php
|
||||
$crudModel = new $crudModel();
|
||||
@endphp
|
||||
<ul class="nav flex-column mb-2">
|
||||
@can('viewAny', $crudModel)
|
||||
<li class="nav-item"><a class="nav-link" href="{{ route(sprintf('%s%s.index', $prefix ?? '', $crudModel->getTable())) }}">{{ __('Liste') }}</a></li>
|
||||
@endcan
|
||||
@can('create', $crudModel)
|
||||
<li class="nav-item"><a class="nav-link" href="{{ route(sprintf('%s%s.create', $prefix ?? '', $crudModel->getTable())) }}">{{ __('Ajouter') }}</a></li>
|
||||
@endcan
|
||||
</ul>
|
||||
<hr>
|
||||
@endcan
|
||||
@endforeach
|
||||
<h6 class="sidebar-heading px-3 mb-1 text-muted">
|
||||
<span>{{ __('Export de segmentation') }}</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item"><a class="nav-link" href="{{ route('questions.export') }}">{{ __('Exporter des questions') }}</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h6 class="sidebar-heading px-3 mb-1 text-muted">
|
||||
<span>{{ __('Export pour newsletter') }}</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item"><a class="nav-link" href="{{ route('customers.export') }}">{{ __('Exporter un fichier CSV') }}</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item">
|
||||
<form action="{{ route('logout') }}" method="POST">
|
||||
@csrf
|
||||
<button class="btn btn-primary">{{ __('Se déconnecter') }}</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
@ -1,78 +1,10 @@
|
|||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Tableau de bord</title>
|
||||
@extends('layouts.app')
|
||||
|
||||
<script src="https://cdn.ckeditor.com/ckeditor5/23.0.0/classic/ckeditor.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
<style>
|
||||
.bd-placeholder-img {
|
||||
font-size: 1.125rem;
|
||||
text-anchor: middle;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.bd-placeholder-img-lg {
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
}
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
width: 100%;
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
.form-signin .checkbox {
|
||||
font-weight: 400;
|
||||
}
|
||||
.form-signin .form-control {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.form-signin .form-control:focus {
|
||||
z-index: 2;
|
||||
}
|
||||
.form-signin input[type="email"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="text-center">
|
||||
@section('content')
|
||||
<div class="login text-center">
|
||||
<form class="form-signin" method="POST" action="{{ route('authenticate') }}">
|
||||
@csrf
|
||||
<img class="mb-4" src="{{ asset('images/logo_ldc.png') }}" alt="LDC Services">
|
||||
<img class="mb-4" src="{{ asset('assets/images/logo_ldc.png') }}" alt="LDC Services">
|
||||
<h1 class="h3 mb-3 font-weight-normal">LDC CRM</h1>
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
|
|
@ -83,12 +15,12 @@
|
|||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<label for="inputEmail" class="sr-only">Adresse email</label>
|
||||
<label for="inputEmail" class="visually-hidden">Adresse email</label>
|
||||
<input type="email" id="inputEmail" class="form-control" placeholder="Adresse email" name="email" value="{{ old('email') }}" required autofocus>
|
||||
<label for="inputPassword" class="sr-only">Mot de passe</label>
|
||||
<label for="inputPassword" class="visually-hidden">Mot de passe</label>
|
||||
<input type="password" id="inputPassword" class="form-control" placeholder="Mot de passe" name="password" required>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Connexion</button>
|
||||
<p class="mt-5 mb-3 text-muted">© LDC Services {{ date('Y') }}</p>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
|
|||
8
resources/views/mail/service-renewed-plain.blade.php
Normal file
8
resources/views/mail/service-renewed-plain.blade.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
{{ config('app.name') }} Service Warning
|
||||
|
||||
Un service vient d'être régénéré sur {{ $appName }}
|
||||
{{ $service->name }} (marque : {{ $service->brand->name }})
|
||||
Régénéré le {{ $service->updated_at->format('D/m/Y H:i') }}
|
||||
par {{ $by }}
|
||||
Celà va empêcher le service de fonctionner tant que les crédentials d'api n'auront pas été mis à jour sur le service concerné, veuillez faire au plus vite !
|
||||
13
resources/views/mail/service-renewed.blade.php
Normal file
13
resources/views/mail/service-renewed.blade.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>{{ config('app.name') }} Service Warning</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Un service vient d'être régénéré sur {{ $appName }}</h1>
|
||||
<h2>{{ $service->name }} (marque : {{ $service->brand->name }})</h2>
|
||||
<h3>Régénéré le {{ $service->updated_at->format('D d/m/Y H:i') }} <br> par {{ $by }}</h3>
|
||||
<p><b>Celà va empêcher le service de fonctionner</b> tant que les crédentials d'api n'auront pas été mis à jour sur le service concerné, veuillez faire au plus vite !</p>
|
||||
</body>
|
||||
</html>
|
||||
4
resources/views/modules/crudAction.blade.php
Normal file
4
resources/views/modules/crudAction.blade.php
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
@if(request()->question)
|
||||
<a href="{{ route('questions.show', request()->question) }}" class="btn btn-success float-end">{{ Str::ucfirst(__('models.common.question')) }}</a>
|
||||
<a href="{{ route('questions.answers.index', request()->question) }}" class="btn btn-dark float-end">{{ Str::ucfirst(__('models.classes.answers')) }}</a>
|
||||
@endif
|
||||
44
resources/views/modules/flashMessage.blade.php
Normal file
44
resources/views/modules/flashMessage.blade.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
@if ($message = Session::get('success'))
|
||||
<div class="alert alert-success alert-dismissible fade show">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
<strong>{!! nl2br(e($message)) !!}</strong>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($message = Session::get('error'))
|
||||
<div class="alert alert-danger alert-dismissible fade show">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
<strong>{!! nl2br(e($message)) !!}</strong>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($message = Session::get('warning'))
|
||||
<div class="alert alert-warning alert-dismissible fade show">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
<strong>{!! nl2br(e($message)) !!}</strong>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($message = Session::get('info'))
|
||||
<div class="alert alert-info alert-dismissible fade show">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
<strong>{!! nl2br(e($message)) !!}</strong>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger alert-dismissible fade show">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
@if ($errors->any())
|
||||
<ul class="list-unstyled">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
53
resources/views/question/export.blade.php
Normal file
53
resources/views/question/export.blade.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('Export')))
|
||||
@section('description', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('Export')))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
<nav aria-label="breadcrumb" class="d-inline">
|
||||
<ol class="breadcrumb d-inline-flex">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{{ route('customers.index') }}">{{ __('models.classes.customers') }}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{{ __('Exporter les réponses au questions') }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mt-5 mb-5" action="{{ route('questions.exportSubmit') }}" method="POST">
|
||||
@csrf
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6 col-md-10 col-12 mb-5">
|
||||
<h1>{{ __('Exporter les réponses au questions') }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6 col-md-10 col-12">
|
||||
<fieldset>
|
||||
<legend>{{ __('La marque concernée') }}</legend>
|
||||
<div class="input-group mb-3">
|
||||
<label class="input-group-text" for="exportBrand">{{ __('Les client de la marque') }}</label>
|
||||
<select class="form-select" id="exportBrand" name="brand" required>
|
||||
<option selected value="">{{ __('Choissez une marque') }}</option>
|
||||
@foreach($brands as $i => $brand)
|
||||
<option value="{{ $brand->id }}">{{ $brand->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center mt-4">
|
||||
<div class="col-lg-6 col-md-10 col-12">
|
||||
<button type="submit" class="btn btn-primary">{{ __('Exporter') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
125
resources/views/question/index.blade.php
Normal file
125
resources/views/question/index.blade.php
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
@extends($viewLayout)
|
||||
|
||||
@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('crud-policies::crud.viewAny')))
|
||||
@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), trans(Str::plural(class_basename($modelClass)))))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
@include('crud-policies::crud.modules.breadcrumb', ['action' => CrudAction::viewAny()])
|
||||
@include('crud-policies::crud.modules.actionbar.bar', ['action' => CrudAction::viewAny()])
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col">
|
||||
<form action="{{ url()->current() }}">
|
||||
<div class="input-group mb-3">
|
||||
<label class="input-group-text" for="brandSelect">{{ __('Filter par Marque') }}</label>
|
||||
<select class="form-select" id="brandSelect">
|
||||
<option value="0" @if(!request()->brand) selected @endif>{{ __('Sélectionnez une marque..') }}</option>
|
||||
@foreach(Brand::all() as $brand)
|
||||
<option value="{{ $brand->id }}" @if(request()->brand == "$brand->id") selected @endif>{{ $brand->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label class="input-group-text bg-warning" for="searchField">🔍🠚</label>
|
||||
<input type="search" id="searchField" name="search" class="form-control" value="{{ request()->search }}" placeholder="Recherche.."/>
|
||||
<input type="text" name="sort_col" class="d-none" value="{{ request()->sort_col }}"/>
|
||||
<input type="text" name="sort_way" class="d-none" value="{{ request()->sort_way }}"/>
|
||||
@if(request()->brand)
|
||||
<input type="hidden" name="brand" class="d-none" value="{{ request()->brand }}"/>
|
||||
@endif
|
||||
<a class="btn btn-danger" href="{{ url()->current() }}">{{ __('crud-policies::crud.reset') }}</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('crud-policies::crud.search') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{ $models->appends(Request::except('rst'))->links() }}
|
||||
<table class="table text-center">
|
||||
<thead class="thead-dark">
|
||||
@include('crud-policies::crud.modules.sorter')
|
||||
</thead>
|
||||
<tbody>
|
||||
@if(count($models))
|
||||
|
||||
{{-- INIT QUERIES for OPTIMIZING --}}
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if($prop['type']->equals(CrudType::order()))
|
||||
@php ${"$modelTable$fieldName"} = $modelClass::max($fieldName); @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsTo()))
|
||||
@php try { $models->load(Str::singular((new $prop['belongsTo']())->getTable())); } catch(\Exception $e) {} @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsToMany()))
|
||||
@php $models->load("$fieldName"); @endphp
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- DISPLAY MODELS --}}
|
||||
@foreach($models as $model)
|
||||
<tr>
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if(in_array(CrudAction::viewAny(), $prop['actions']))
|
||||
@switch($prop['type'])
|
||||
@case(CrudType::belongsToMany() and $prop['belongsToMany'] === \App\Models\Project::class)
|
||||
<td>
|
||||
@foreach($model->{$fieldName} as $pSite)
|
||||
<a href="{{ CrudController::getRoutePrefixed($pSite->getTable().'.show', $pSite) }}">{{ $pSite->{$prop['belongsToManyLabel']} }}</a>
|
||||
@endforeach
|
||||
</td>
|
||||
@break
|
||||
@case(CrudType::password())
|
||||
{{-- Ignore --}}
|
||||
@break
|
||||
@default
|
||||
<td>@include('crud-policies::crud.printfield', [
|
||||
'action' => CrudAction::viewAny(),
|
||||
'field' => $model->{$fieldName},
|
||||
'props' => $prop,
|
||||
"$modelTable$fieldName" => ${"$modelTable$fieldName"} ?? null
|
||||
])</td>
|
||||
@endswitch
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- MODEL ACTIONS --}}
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="{{ Str::plural(__('crud-policies::crud.action')) }}">
|
||||
@can('view', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.show", $model) }}" class="btn btn-sm btn-primary">{{ __('crud-policies::crud.view') }}</a>
|
||||
@endcan
|
||||
@can('update', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.edit", $model) }}" class="btn btn-sm btn-info">{{ __('crud-policies::crud.edit') }}</a>
|
||||
@endcan
|
||||
@can('delete', $model)
|
||||
<form action="{{ CrudController::getRoutePrefixed("$modelTable.destroy", $model) }}" method="POST" onsubmit="__CRUD.confirmDelete(event)">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-danger">{{ __('crud-policies::crud.delete') }}</button>
|
||||
</form>
|
||||
@endcan
|
||||
@can('viewAny', \App\Models\Answer::class)
|
||||
<a href="{{ CrudController::getRoutePrefixed("questions.answers.index", $model) }}" class="btn btn-sm btn-dark">{{ Str::ucfirst(__('models.classes.answers')) }}</a>
|
||||
@endcan
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="{{ count($modelClass::getEditableProperties()) }}">
|
||||
{{ __('crud-policies::crud.nothingtoshow') }}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $models->links() }}
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
158
resources/views/service/index.blade.php
Normal file
158
resources/views/service/index.blade.php
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
@extends($viewLayout)
|
||||
|
||||
@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('crud-policies::crud.viewAny')))
|
||||
@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), trans(Str::plural(class_basename($modelClass)))))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
@include('crud-policies::crud.modules.breadcrumb', ['action' => CrudAction::viewAny()])
|
||||
@include('crud-policies::crud.modules.actionbar.bar', ['action' => CrudAction::viewAny()])
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-end">
|
||||
<div class="col-6">
|
||||
<form action="{{ url()->current() }}">
|
||||
<div class="input-group mb-3">
|
||||
<input type="search" name="search" class="form-control" value="{{ request()->search }}" placeholder="Recherche.."/>
|
||||
<input type="text" name="sort_col" class="d-none" value="{{ request()->sort_col }}"/>
|
||||
<input type="text" name="sort_way" class="d-none" value="{{ request()->sort_way }}"/>
|
||||
@if(request()->brand)
|
||||
<input type="hidden" name="brand" class="d-none" value="{{ request()->brand }}"/>
|
||||
@endif
|
||||
<a class="btn btn-danger" href="{{ url()->current() }}">{{ __('crud-policies::crud.reset') }}</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('crud-policies::crud.search') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table text-center">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
@foreach ($modelClass::getEditableProperties() as $colname => $prop)
|
||||
@if(in_array(CrudAction::viewAny(), $prop['actions']))
|
||||
@switch($prop['type'])
|
||||
@case(CrudType::password())
|
||||
{{-- Ignore --}}
|
||||
@break
|
||||
@default
|
||||
<th scope="col">
|
||||
{{ $prop['label'] }}
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'desc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead asc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'asc']) }}"> ↓ </a>
|
||||
@endif
|
||||
@if(!session("crud.$modelTable.sort_way") or session("crud.$modelTable.sort_col") !== $colname or (session("crud.$modelTable.sort_way") === 'asc' and session("crud.$modelTable.sort_col") === $colname))
|
||||
<a class="col_sort text-secondary lead desc" href="{{ request()->fullUrlWithQuery(['sort_col' => $colname, 'sort_way' => 'desc']) }}"> ↑ </a>
|
||||
@endif
|
||||
</th>
|
||||
@endswitch
|
||||
@endif
|
||||
@endforeach
|
||||
<th scope="col">
|
||||
{{ __('Date du Bearer token')}}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{{ __('Régénerer un token')}}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{{ __('Date de création')}}
|
||||
</th>
|
||||
<th scope="col">
|
||||
@if(session("crud.$modelTable.sort_way") and session("crud.$modelTable.sort_col"))
|
||||
<a href="{{ request()->fullUrlWithQuery(['rst' => 'true']) }}" class="btn btn-small btn-danger">⌫</a>
|
||||
@endif
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if(count($models))
|
||||
|
||||
{{-- INIT QUERIES for OPTIMIZING --}}
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if($prop['type']->equals(CrudType::order()))
|
||||
@php ${"$modelTable$fieldName"} = $modelClass::max($fieldName); @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsTo()))
|
||||
@php try { $models->load(Str::singular((new $prop['belongsTo']())->getTable())); } catch(\Exception $e) {} @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsToMany()))
|
||||
@php $models->load("$fieldName"); @endphp
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- DISPLAY MODELS --}}
|
||||
@foreach($models as $model)
|
||||
<tr>
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if(in_array(CrudAction::viewAny(), $prop['actions']))
|
||||
@switch($prop['type'])
|
||||
@case(CrudType::belongsToMany() and $prop['belongsToMany'] === \App\Models\Project::class)
|
||||
<td>
|
||||
@foreach($model->{$fieldName} as $pSite)
|
||||
<a href="{{ CrudController::getRoutePrefixed($pSite->getTable().'.show', $pSite) }}">{{ $pSite->{$prop['belongsToManyLabel']} }}</a>
|
||||
@endforeach
|
||||
</td>
|
||||
@break
|
||||
@case(CrudType::password())
|
||||
{{-- Ignore --}}
|
||||
@break
|
||||
@default
|
||||
<td>@include('crud-policies::crud.printfield', [
|
||||
'action' => CrudAction::viewAny(),
|
||||
'field' => $model->{$fieldName},
|
||||
'props' => $prop,
|
||||
"$modelTable$fieldName" => ${"$modelTable$fieldName"} ?? null
|
||||
])</td>
|
||||
@endswitch
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- INFO COLS --}}
|
||||
<td>{{ Carbon::parse($model->bearer_token_date)->format('m/d/Y à H:i') }}</td>
|
||||
<td><form class="genToken" action="{{ route('generate-token-service', $model) }}" method="POST">@csrf<button class="btn btn-success">Générer</button></form></td>
|
||||
<td>{{ $model->created_at->format('m/d/Y à H:i') }}</td>
|
||||
|
||||
{{-- MODEL ACTIONS --}}
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="{{ Str::plural(__('crud-policies::crud.action')) }}">
|
||||
@can('view', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.show", $model) }}" class="btn btn-sm btn-primary">{{ __('crud-policies::crud.view') }}</a>
|
||||
@endcan
|
||||
@can('update', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.edit", $model) }}" class="btn btn-sm btn-info">{{ __('crud-policies::crud.edit') }}</a>
|
||||
@endcan
|
||||
@can('delete', $model)
|
||||
<form action="{{ CrudController::getRoutePrefixed("$modelTable.destroy", $model) }}" method="POST" onsubmit="__CRUD.confirmDelete(event)">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-danger">{{ __('crud-policies::crud.delete') }}</button>
|
||||
</form>
|
||||
@endcan
|
||||
@can('viewAny', \App\Models\Log::class)
|
||||
<a href="{{ CrudController::getRoutePrefixed("sites.logs.index", $model) }}" class="btn btn-sm btn-dark">{{ __('Journaux') }}</a>
|
||||
@endcan
|
||||
@can('viewAny', \App\Models\File::class)
|
||||
<a href="{{ CrudController::getRoutePrefixed("sites.files.index", $model) }}" class="btn btn-sm btn-dark">{{ __('Fichiers') }}</a>
|
||||
@endcan
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="{{ count($modelClass::getEditableProperties()) }}">
|
||||
{{ __('crud-policies::crud.nothingtoshow') }}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $models->links() }}
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h2>{{ __('Gestion des services') }} <small class="text-muted">{{ __('Liste') }}</small></h2>
|
||||
@if (session('success'))
|
||||
<span class="text-success text-center">{!! session('success') !!}</span>
|
||||
@endif
|
||||
@if (session('error'))
|
||||
<span class="text-danger text-center">{!! session('error') !!}</span>
|
||||
@endif
|
||||
<a href="{{ route('manage-service') }}" class="btn btn-sm btn-primary float-right">{{ __('Ajouter') }}</a>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>{{ __('Nom') }}</th>
|
||||
<th>{{ __('Marque') }}</th>
|
||||
<th>{{ __('Date du token') }}</th>
|
||||
<th>{{ __('Regénérer un token') }}</th>
|
||||
<th>{{ __('Date de création') }}</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($services as $service)
|
||||
<tr>
|
||||
<td>{{ $service->name }}</td>
|
||||
<td>{{ $service->brand->name }}</td>
|
||||
<td>{{ Carbon::parse($service->bearer_token_date)->format('d/m/Y à H:i') }}</td>
|
||||
<td><a href="{{ route('generate-token-service', $service) }}" class="btn btn-sm btn-success">{{ __('Générer') }}</a></td>
|
||||
<td>{{ Carbon::parse($service->created_at)->format('d/m/Y à H:i') }}</td>
|
||||
<td><a href="{{ route('manage-service', $service) }}" class="btn btn-sm btn-success">{{ __('Modifier') }}</a></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endsection
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h2>{{ __('Gestion des services') }} <small class="text-muted">{{ __('Gestion') }}</small></h2>
|
||||
@if ($errors->any())
|
||||
<ul class="text-danger text-center">
|
||||
@foreach(session('errors')->all(':message') as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
@if (session('success'))
|
||||
<span class="text-success text-center">{!! session('success') !!}</span>
|
||||
@endif
|
||||
<a href="{{ route('services') }}" class="btn btn-sm btn-primary float-right">{{ __('Retour') }}</a>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<form action="{{ route('manage-service', $service ? $service->id : null) }}" method="POST">
|
||||
@csrf
|
||||
<div class="form-group form-row">
|
||||
<label class="col-form-label col" for="name">{{ __('Nom du service') }}</label>
|
||||
<input type="text" id="name" name="name" class="form-control col" value="{{ $service ? $service->name : null }}">
|
||||
</div>
|
||||
@if (!$edit)
|
||||
<div class="form-group form-row">
|
||||
<label class="col-form-label col" for="brand_id">{{ __('Marque associée') }}</label>
|
||||
<select class="custom-select col" id="brand_id" name="brand_id">
|
||||
@foreach($brands as $brand)
|
||||
<option value="{{ $brand->id }}">{{ $brand->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
@else
|
||||
<input type="hidden" value="{{ $service->brand->id }}" name="brand_id">
|
||||
@endif
|
||||
<div class="text-center">
|
||||
<input type="submit" class="btn btn-success" value="{{ __('Enregistrer') }}">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<search-optin dbbrands='@json($brands)'></search-optin>
|
||||
@endsection
|
||||
121
resources/views/single_optin/index.blade.php
Normal file
121
resources/views/single_optin/index.blade.php
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
@extends($viewLayout)
|
||||
|
||||
@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('crud-policies::crud.viewAny')))
|
||||
@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), trans(Str::plural(class_basename($modelClass)))))
|
||||
@section('metaIndex', 'noindex,nofollow')
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
@include('crud-policies::crud.modules.flashMessage')
|
||||
<div class="card-header">
|
||||
@include('crud-policies::crud.modules.breadcrumb', ['action' => CrudAction::viewAny()])
|
||||
@include('crud-policies::crud.modules.actionbar.bar', ['action' => CrudAction::viewAny()])
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col">
|
||||
<form action="{{ url()->current() }}">
|
||||
<div class="input-group mb-3">
|
||||
<label class="input-group-text" for="brandSelect">Filter par Marque</label>
|
||||
<select class="form-select" id="brandSelect">
|
||||
<option value="0" @if(!request()->brand) selected @endif>Sélectionnez une marque..</option>
|
||||
@foreach(Brand::all() as $brand)
|
||||
<option value="{{ $brand->id }}" @if(request()->brand == "$brand->id") selected @endif>{{ $brand->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label class="input-group-text bg-warning" for="searchField">🔍🠚</label>
|
||||
<input type="search" id="searchField" name="search" class="form-control" value="{{ request()->search }}" placeholder="Recherche.."/>
|
||||
<input type="text" name="sort_col" class="d-none" value="{{ request()->sort_col }}"/>
|
||||
<input type="text" name="sort_way" class="d-none" value="{{ request()->sort_way }}"/>
|
||||
@if(request()->brand)
|
||||
<input type="hidden" name="brand" class="d-none" value="{{ request()->brand }}"/>
|
||||
@endif
|
||||
<a class="btn btn-danger" href="{{ url()->current() }}">{{ __('crud-policies::crud.reset') }}</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('crud-policies::crud.search') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table text-center">
|
||||
<thead class="thead-dark">
|
||||
@include('crud-policies::crud.modules.sorter')
|
||||
</thead>
|
||||
<tbody>
|
||||
@if(count($models))
|
||||
|
||||
{{-- INIT QUERIES for OPTIMIZING --}}
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if($prop['type']->equals(CrudType::order()))
|
||||
@php ${"$modelTable$fieldName"} = $modelClass::max($fieldName); @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsTo()))
|
||||
@php try { $models->load(Str::singular((new $prop['belongsTo']())->getTable())); } catch(\Exception $e) {} @endphp
|
||||
@endif
|
||||
@if($prop['type']->equals(CrudType::belongsToMany()))
|
||||
@php $models->load("$fieldName"); @endphp
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- DISPLAY MODELS --}}
|
||||
@foreach($models as $model)
|
||||
<tr>
|
||||
@foreach ($modelClass::getEditableProperties() as $fieldName => $prop)
|
||||
@if(in_array(CrudAction::viewAny(), $prop['actions']))
|
||||
@switch($prop['type'])
|
||||
@case(CrudType::belongsToMany() and $prop['belongsToMany'] === \App\Models\Project::class)
|
||||
<td>
|
||||
@foreach($model->{$fieldName} as $pSite)
|
||||
<a href="{{ CrudController::getRoutePrefixed($pSite->getTable().'.show', $pSite) }}">{{ $pSite->{$prop['belongsToManyLabel']} }}</a>
|
||||
@endforeach
|
||||
</td>
|
||||
@break
|
||||
@case(CrudType::password())
|
||||
{{-- Ignore --}}
|
||||
@break
|
||||
@default
|
||||
<td>@include('crud-policies::crud.printfield', [
|
||||
'action' => CrudAction::viewAny(),
|
||||
'field' => $model->{$fieldName},
|
||||
'props' => $prop,
|
||||
"$modelTable$fieldName" => ${"$modelTable$fieldName"} ?? null
|
||||
])</td>
|
||||
@endswitch
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- MODEL ACTIONS --}}
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="{{ Str::plural(__('crud-policies::crud.action')) }}">
|
||||
@can('view', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.show", $model) }}" class="btn btn-sm btn-primary">{{ __('crud-policies::crud.view') }}</a>
|
||||
@endcan
|
||||
@can('update', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.edit", $model) }}" class="btn btn-sm btn-info">{{ __('crud-policies::crud.edit') }}</a>
|
||||
@endcan
|
||||
@can('delete', $model)
|
||||
<form action="{{ CrudController::getRoutePrefixed("$modelTable.destroy", $model) }}" method="POST" onsubmit="__CRUD.confirmDelete(event)">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-danger">{{ __('crud-policies::crud.delete') }}</button>
|
||||
</form>
|
||||
@endcan
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="{{ count($modelClass::getEditableProperties()) }}">
|
||||
{{ __('crud-policies::crud.nothingtoshow') }}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $models->links() }}
|
||||
</div>
|
||||
</div>
|
||||
@include('crud-policies::crud.modules.scriptConstants')
|
||||
@endsection
|
||||
21
resources/views/vendor/crud-policies/crud/modules/actionbar/bar.blade.php
vendored
Normal file
21
resources/views/vendor/crud-policies/crud/modules/actionbar/bar.blade.php
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<div class="btn-group float-end" role="group" aria-label="{{ Str::plural(__('crud-policies::crud.action')) }}">
|
||||
@switch($action)
|
||||
@case(CrudAction::viewAny())
|
||||
@include('modules.crudAction')
|
||||
@include('crud-policies::crud.modules.actionbar.create')
|
||||
@break
|
||||
@case(CrudAction::view())
|
||||
@include('modules.crudAction')
|
||||
@include('crud-policies::crud.modules.actionbar.update')
|
||||
@include('crud-policies::crud.modules.actionbar.delete')
|
||||
@break
|
||||
@case(CrudAction::create())
|
||||
@include('modules.crudAction')
|
||||
@break
|
||||
@case(CrudAction::update())
|
||||
@include('modules.crudAction')
|
||||
@include('crud-policies::crud.modules.actionbar.view')
|
||||
@include('crud-policies::crud.modules.actionbar.delete')
|
||||
@break
|
||||
@endswitch
|
||||
</div>
|
||||
3
resources/views/vendor/crud-policies/crud/modules/actionbar/create.blade.php
vendored
Normal file
3
resources/views/vendor/crud-policies/crud/modules/actionbar/create.blade.php
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@can('create', $modelClass)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.create") }}" class="btn btn-primary float-end">{{ __('crud-policies::crud.create') }}</a>
|
||||
@endcan
|
||||
7
resources/views/vendor/crud-policies/crud/modules/actionbar/delete.blade.php
vendored
Normal file
7
resources/views/vendor/crud-policies/crud/modules/actionbar/delete.blade.php
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
@can('delete', $model)
|
||||
<form action="{{ CrudController::getRoutePrefixed("$modelTable.destroy", $model)}}" method="POST" onsubmit="__CRUD.confirmDelete(event)">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-danger">{{ __('crud-policies::crud.delete') }}</button>
|
||||
</form>
|
||||
@endcan
|
||||
3
resources/views/vendor/crud-policies/crud/modules/actionbar/update.blade.php
vendored
Normal file
3
resources/views/vendor/crud-policies/crud/modules/actionbar/update.blade.php
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@can('update', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.edit", $model)}}" class="btn btn-info ">{{ __('crud-policies::crud.update') }}</a>
|
||||
@endcan
|
||||
3
resources/views/vendor/crud-policies/crud/modules/actionbar/view.blade.php
vendored
Normal file
3
resources/views/vendor/crud-policies/crud/modules/actionbar/view.blade.php
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@can('view', $model)
|
||||
<a href="{{ CrudController::getRoutePrefixed("$modelTable.show", $model) }}" class="btn btn-primary ">{{ __('crud-policies::crud.view') }}</a>
|
||||
@endcan
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Controllers\AnswerController;
|
||||
use App\Http\Controllers\BrandController;
|
||||
use App\Http\Controllers\CustomerController;
|
||||
use App\Http\Controllers\LoginController;
|
||||
use App\Http\Controllers\QuestionController;
|
||||
use App\Http\Controllers\ServiceController;
|
||||
use App\Http\Controllers\SingleOptinsController;
|
||||
use App\Http\Controllers\SingleOptinController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
/*
|
||||
|
|
@ -22,30 +24,38 @@ Route::get('/login', [LoginController::class, 'index'])->name('login');
|
|||
Route::post('/login', [LoginController::class, 'authenticate'])->name('authenticate');
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::get('/', function () {
|
||||
return redirect()->route('customers');
|
||||
});
|
||||
Route::get('/logout', [LoginController::class, 'logout'])->name('logout');
|
||||
return redirect()->route('brands.index');
|
||||
})->name('home');
|
||||
Route::post('/logout', [LoginController::class, 'logout'])->name('logout');
|
||||
|
||||
// Marques
|
||||
Route::get('/brands', [BrandController::class, 'index'])->name('brands');
|
||||
Route::match(['get', 'post'], '/brand/manage/{brand?}', [BrandController::class, 'manage'])->name('manage-brand');
|
||||
Route::resource('brands', BrandController::class)->except([
|
||||
'delete'
|
||||
]);
|
||||
Route::match(['get', 'post'], '/brand/manage/{brand?}', [BrandController::class, 'manage'])
|
||||
->name('manage-brand');
|
||||
|
||||
// Services
|
||||
Route::get('/services', [ServiceController::class, 'index'])->name('services');
|
||||
Route::match(['get', 'post'], '/service/manage/{service?}', [ServiceController::class, 'manage'])
|
||||
->name('manage-service');
|
||||
Route::get('/services/{service}/token/generate', [ServiceController::class, 'generateApiToken'])
|
||||
Route::resource('services', ServiceController::class)->except([
|
||||
'delete'
|
||||
]);
|
||||
Route::post('/services/{service}/token/generate', [ServiceController::class, 'generateApiToken'])
|
||||
->name('generate-token-service');
|
||||
|
||||
// Clients
|
||||
Route::get('/customers', [CustomerController::class, 'index'])->name('customers');
|
||||
Route::get('/customers/filter/{texte}/{brand?}', [CustomerController::class, 'filter'])->name('filter-customer');
|
||||
Route::get('/customer/{customer}/{brand}', [CustomerController::class, 'show'])->name('show-customer');
|
||||
Route::delete('/customer/{customer}/{brand}', [CustomerController::class, 'delete'])->name('customers.delete');
|
||||
Route::get('/customers', [CustomerController::class, 'index'])->name('customers.index');
|
||||
Route::get('/customers/{customer}/{brand}', [CustomerController::class, 'show'])->name('customers.show');
|
||||
Route::delete('/customers/{customer}/{brand}', [CustomerController::class, 'delete'])->name('customers.delete');
|
||||
Route::get('/customers/export', [CustomerController::class, 'export'])->name('customers.export');
|
||||
Route::post('/customers/export', [CustomerController::class, 'exportSubmit'])->name('customers.exportSubmit');
|
||||
|
||||
// Single optins
|
||||
Route::get('/single-optins', [SingleOptinsController::class, 'index'])->name('single-optins');
|
||||
Route::get('/single-optins/filter/{texte}/{brandId?}', [SingleOptinsController::class, 'filter'])
|
||||
->name('filter-single-optins');
|
||||
Route::post('/single-optins/{id}/delete', [SingleOptinsController::class, 'delete'])->name('single-optins-delete');
|
||||
Route::resource('single_optins', SingleOptinController::class);
|
||||
Route::post('/single_optins/{id}/delete', [SingleOptinController::class, 'delete'])->name('single-optins-delete');
|
||||
|
||||
// Questions
|
||||
Route::get('/questions/export', [QuestionController::class, 'export'])->name('questions.export');
|
||||
Route::post('/questions/export', [QuestionController::class, 'exportSubmit'])->name('questions.exportSubmit');
|
||||
Route::resource('questions', QuestionController::class);
|
||||
Route::resource('questions.answers', AnswerController::class);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class CrmClientV2RouterTest extends CrmClientTester
|
|||
$this->assertEquals($route->methods(), $routes[$route->getName()]['methods']);
|
||||
$this->assertEquals($route->uri(), $routes[$route->getName()]['uri']);
|
||||
} else {
|
||||
$this->assertArrayNotHasKey($route->getName(), $routes);
|
||||
$this->assertArrayNotHasKey($route->getName() ?? '', $routes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
58
webpack.mix.js
vendored
58
webpack.mix.js
vendored
|
|
@ -1,15 +1,49 @@
|
|||
const path = require('path');
|
||||
const mix = require('laravel-mix');
|
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
require('laravel-mix-polyfill');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Mix Asset Management
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Mix provides a clean, fluent API for defining some Webpack build steps
|
||||
| for your Laravel applications. By default, we are compiling the CSS
|
||||
| file for the application as well as bundling up all the JS files.
|
||||
|
|
||||
*/
|
||||
mix.webpackConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve('resources/assets')
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new CleanWebpackPlugin({
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'css/*',
|
||||
'js/*',
|
||||
'images/*',
|
||||
'fonts/*',
|
||||
'assets/*'
|
||||
]
|
||||
})
|
||||
],
|
||||
});
|
||||
|
||||
mix.js('resources/js/app.js', 'public/js')
|
||||
.sass('resources/sass/app.scss', 'public/css');
|
||||
let assetDir = 'assets';
|
||||
mix.options({
|
||||
fileLoaderDirs: {
|
||||
images: `${assetDir}/images`,
|
||||
fonts: `${assetDir}/fonts`
|
||||
},
|
||||
postCss: [
|
||||
require('postcss-discard-comments')({
|
||||
removeAll: true
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
// mix Backend
|
||||
mix.js("resources/js/back.js", "public/js/preload-back.js")
|
||||
.sass("resources/sass/back.scss", "public/css/preload-back.css")
|
||||
// .vue()
|
||||
.polyfill({
|
||||
enabled: true,
|
||||
useBuiltIns: "usage",
|
||||
targets: { "firefox": "50", "ie": 11 }
|
||||
});
|
||||
|
||||
// Copy Blade Images Assets
|
||||
mix.copyDirectory('resources/assets', 'public/assets');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue