mirror of
https://github.com/openclassify/openclassify.git
synced 2026-01-11 18:01:10 -06:00
commit
255cee809e
@ -0,0 +1,59 @@
|
||||
$(document).ready( function () {
|
||||
$('#stockReport').DataTable({
|
||||
ajax: '/admin/api/classified/report/stock',
|
||||
order: [[ 1, "asc" ]],
|
||||
columns: [
|
||||
{
|
||||
data: 'name',
|
||||
render: function ( data, type, row, meta ) {
|
||||
return `
|
||||
<a href="/admin/advs/edit/${row.id}" class="text-info">
|
||||
${data ?? productsReportTrans.undefined_product}
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
},
|
||||
{ data: 'stock' },
|
||||
],
|
||||
});
|
||||
|
||||
$('#activePassiveReport').DataTable({
|
||||
ajax: '/admin/api/classified/report/status',
|
||||
columns: [
|
||||
{ data: 'status' },
|
||||
{ data: 'count' },
|
||||
],
|
||||
});
|
||||
|
||||
$('#unexplainedReport').DataTable({
|
||||
ajax: '/admin/api/classified/report/unexplained',
|
||||
columns: [
|
||||
{
|
||||
data: 'name',
|
||||
render: function ( data, type, row, meta ) {
|
||||
return `
|
||||
<a href="/admin/advs/edit/${row.id}" class="text-info">
|
||||
${data ?? productsReportTrans.undefined_product}
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
$('#noImageReport').DataTable({
|
||||
ajax: '/admin/api/classified/report/no-image',
|
||||
columns: [
|
||||
{
|
||||
data: 'name',
|
||||
render: function ( data, type, row, meta ) {
|
||||
return `
|
||||
<a href="/admin/advs/edit/${row.id}" class="text-info">
|
||||
${data ?? productsReportTrans.undefined_product}
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
},
|
||||
],
|
||||
});
|
||||
} );
|
||||
@ -383,4 +383,13 @@ return [
|
||||
'name_a_z' => 'Name (A to Z)',
|
||||
'name_z_a' => 'Name (Z to A)',
|
||||
'select_lang_ads' => 'select the language of the ads',
|
||||
|
||||
// Report
|
||||
'product_stock_report' => 'Product Stock Report',
|
||||
'active_passive_products_report' => 'Active-Passive Products Report',
|
||||
'unexplained_products_report' => 'Unexplained Products Report',
|
||||
'non_image_products_report' => 'Non-Image Products Report',
|
||||
'product' => 'Product',
|
||||
'count' => 'Count',
|
||||
'undefined_product' => 'Undefined Product',
|
||||
];
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
<div class="row">
|
||||
{% set reports = [
|
||||
{
|
||||
'title': trans('visiosoft.module.advs::field.product_stock_report'),
|
||||
'id': 'stockReport',
|
||||
'columns': [
|
||||
trans('visiosoft.module.advs::field.product'),
|
||||
trans('visiosoft.module.advs::field.stock.name'),
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': trans('visiosoft.module.advs::field.active_passive_products_report'),
|
||||
'id': 'activePassiveReport',
|
||||
'columns': [
|
||||
trans('visiosoft.module.advs::field.status.name'),
|
||||
trans('visiosoft.module.advs::field.count'),
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': trans('visiosoft.module.advs::field.unexplained_products_report'),
|
||||
'id': 'unexplainedReport',
|
||||
'columns': [
|
||||
trans('visiosoft.module.advs::field.product'),
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': trans('visiosoft.module.advs::field.non_image_products_report'),
|
||||
'id': 'noImageReport',
|
||||
'columns': [
|
||||
trans('visiosoft.module.advs::field.product'),
|
||||
],
|
||||
},
|
||||
] %}
|
||||
|
||||
{% for report in reports %}
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary">
|
||||
<h5 class="card-title text-white">{{ report.title }}</h5>
|
||||
</div>
|
||||
|
||||
<div class="card-block">
|
||||
<table id="{{ report.id }}" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for column in report.columns %}
|
||||
<th>{{ column }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const productsReportTrans = {
|
||||
undefined_product: `{{ trans('visiosoft.module.advs::field.undefined_product') }}`,
|
||||
}
|
||||
</script>
|
||||
|
||||
{{ asset_add('scripts.js', 'visiosoft.module.advs::js/admin/dashboard/report.js') }}
|
||||
@ -543,4 +543,13 @@ class AdvModel extends AdvsAdvsEntryModel implements AdvInterface
|
||||
|
||||
return $lastCat;
|
||||
}
|
||||
|
||||
public function scopeCurrent($query)
|
||||
{
|
||||
return $query
|
||||
->whereDate('finish_at', '>=', date("Y-m-d H:i:s"))
|
||||
->where('status', '=', 'approved')
|
||||
->where('slug', '!=', '')
|
||||
->orderBy('publish_at', 'desc');
|
||||
}
|
||||
}
|
||||
|
||||
@ -592,4 +592,63 @@ class AdvRepository extends EntryRepository implements AdvRepositoryInterface
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getStockReport()
|
||||
{
|
||||
return $this->newQuery()
|
||||
->current()
|
||||
->select('stock', 'name', 'advs_advs.id', 'slug')
|
||||
->where('is_get_adv', true)
|
||||
->where('stock', '<=', 10)
|
||||
->leftJoin('advs_advs_translations as classified_trans', function ($join) {
|
||||
$join->on('advs_advs.id', '=', 'classified_trans.entry_id');
|
||||
$join->whereIn('locale', [config('app.locale'), setting_value('streams::default_locale'), 'en']);
|
||||
})
|
||||
->get();
|
||||
}
|
||||
|
||||
public function getAllClassifiedsCount()
|
||||
{
|
||||
return $this->newQuery()
|
||||
->count();
|
||||
}
|
||||
|
||||
public function getCurrentClassifiedsCount()
|
||||
{
|
||||
return $this->newQuery()
|
||||
->current()
|
||||
->count();
|
||||
}
|
||||
|
||||
public function getUnexplainedClassifiedsReport()
|
||||
{
|
||||
return $this->newQuery()
|
||||
->current()
|
||||
->select('name', 'advs_advs.id', 'slug')
|
||||
->where(function ($query) {
|
||||
$query->where('advs_desc', '=', '')
|
||||
->orWhereNull('advs_desc');
|
||||
})
|
||||
->leftJoin('advs_advs_translations as classified_trans', function ($join) {
|
||||
$join->on('advs_advs.id', '=', 'classified_trans.entry_id');
|
||||
$join->whereIn('locale', [config('app.locale'), setting_value('streams::default_locale'), 'en']);
|
||||
})
|
||||
->get();
|
||||
}
|
||||
|
||||
public function getNoImageClassifiedsReport()
|
||||
{
|
||||
return $this->newQuery()
|
||||
->current()
|
||||
->select('name', 'advs_advs.id', 'slug')
|
||||
->where(function ($query) {
|
||||
$query->where('cover_photo', '=', '')
|
||||
->orWhereNull('cover_photo');
|
||||
})
|
||||
->leftJoin('advs_advs_translations as classified_trans', function ($join) {
|
||||
$join->on('advs_advs.id', '=', 'classified_trans.entry_id');
|
||||
$join->whereIn('locale', [config('app.locale'), setting_value('streams::default_locale'), 'en']);
|
||||
})
|
||||
->get();
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,4 +97,6 @@ interface AdvInterface extends EntryInterface
|
||||
public function getCatsIDs();
|
||||
|
||||
public function lastCategory();
|
||||
|
||||
public function scopeCurrent($query);
|
||||
}
|
||||
|
||||
@ -60,4 +60,14 @@ interface AdvRepositoryInterface extends EntryRepositoryInterface
|
||||
public function findByCFJSON($key, $value);
|
||||
|
||||
public function uploadImage();
|
||||
|
||||
public function getStockReport();
|
||||
|
||||
public function getAllClassifiedsCount();
|
||||
|
||||
public function getCurrentClassifiedsCount();
|
||||
|
||||
public function getUnexplainedClassifiedsReport();
|
||||
|
||||
public function getNoImageClassifiedsReport();
|
||||
}
|
||||
|
||||
@ -248,6 +248,12 @@ class AdvsModuleServiceProvider extends AddonServiceProvider
|
||||
'as' => 'visiosoft.module.advs::ad.change.status',
|
||||
'uses' => 'Visiosoft\AdvsModule\Http\Controller\StatusController@change'
|
||||
],
|
||||
|
||||
// Admin ReportController
|
||||
'admin/api/classified/report/stock' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ReportController@stock',
|
||||
'admin/api/classified/report/status' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ReportController@status',
|
||||
'admin/api/classified/report/unexplained' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ReportController@unexplained',
|
||||
'admin/api/classified/report/no-image' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ReportController@noImage',
|
||||
];
|
||||
|
||||
protected $middleware = [
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
<?php namespace Visiosoft\AdvsModule\Http\Controller\Admin;
|
||||
|
||||
use Anomaly\Streams\Platform\Http\Controller\AdminController;
|
||||
use Visiosoft\AdvsModule\Adv\Contract\AdvRepositoryInterface;
|
||||
|
||||
class ReportController extends AdminController
|
||||
{
|
||||
protected $advRepository;
|
||||
|
||||
public function __construct(AdvRepositoryInterface $advRepository)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->advRepository = $advRepository;
|
||||
}
|
||||
|
||||
public function stock()
|
||||
{
|
||||
return [
|
||||
'data' => $this->advRepository->getStockReport()
|
||||
];
|
||||
}
|
||||
|
||||
public function status()
|
||||
{
|
||||
$all = $this->advRepository->getAllClassifiedsCount();
|
||||
$active = $this->advRepository->getCurrentClassifiedsCount();
|
||||
|
||||
return [
|
||||
'data' => [
|
||||
[
|
||||
'status' => 'Active',
|
||||
'count' => $active,
|
||||
],
|
||||
[
|
||||
'status' => 'Passive',
|
||||
'count' => $all - $active,
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function unexplained()
|
||||
{
|
||||
return [
|
||||
'data' => $this->advRepository->getUnexplainedClassifiedsReport()
|
||||
];
|
||||
}
|
||||
|
||||
public function noImage()
|
||||
{
|
||||
return [
|
||||
'data' => $this->advRepository->getNoImageClassifiedsReport()
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
$('.categories-list .show-all').on('click', function () {
|
||||
$(this).siblings('.hidden-category').toggleClass('hidden')
|
||||
$(this).find('a span').toggleClass('hidden')
|
||||
})
|
||||
$(this).siblings('.hidden-category').toggleClass('hidden');
|
||||
$(this).find('a span').toggleClass('hidden');
|
||||
});
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
$(document).ready( function () {
|
||||
$('#newMemberReport').DataTable({
|
||||
ajax: '/admin/api/profile/report/latest',
|
||||
order: [[ 1, "desc" ]],
|
||||
columns: [
|
||||
{ data: 'member', defaultContent: usersReportTrans.undefined_member },
|
||||
{ data: 'date' },
|
||||
],
|
||||
});
|
||||
|
||||
$('#loginMemberReport').DataTable({
|
||||
ajax: '/admin/api/profile/report/login',
|
||||
order: [[ 1, "desc" ]],
|
||||
columns: [
|
||||
{ data: 'member', defaultContent: usersReportTrans.undefined_member },
|
||||
{ data: 'date' },
|
||||
],
|
||||
});
|
||||
} );
|
||||
@ -496,4 +496,12 @@ return [
|
||||
'receive_messages_email' => [
|
||||
'name' => 'Receive Messages Email',
|
||||
],
|
||||
|
||||
// Report
|
||||
'member' => 'Member',
|
||||
'registered_at' => 'Registered At',
|
||||
'login_at' => 'Login At',
|
||||
'undefined_member' => 'Undefined Member',
|
||||
'new_membership_report' => 'New Membership Report',
|
||||
'member_login_reports' => 'Member Login Reports',
|
||||
];
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
<div class="row">
|
||||
{% set reports = [
|
||||
{
|
||||
'title': trans('visiosoft.module.profile::field.new_membership_report'),
|
||||
'id': 'newMemberReport',
|
||||
'columns': [
|
||||
trans('visiosoft.module.profile::field.member'),
|
||||
trans('visiosoft.module.profile::field.registered_at'),
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': trans('visiosoft.module.profile::field.member_login_reports'),
|
||||
'id': 'loginMemberReport',
|
||||
'columns': [
|
||||
trans('visiosoft.module.profile::field.member'),
|
||||
trans('visiosoft.module.profile::field.login_at'),
|
||||
],
|
||||
},
|
||||
] %}
|
||||
|
||||
{% for report in reports %}
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-warning">
|
||||
<h5 class="card-title text-white">{{ report.title }}</h5>
|
||||
</div>
|
||||
|
||||
<div class="card-block">
|
||||
<table id="{{ report.id }}" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for column in report.columns %}
|
||||
<th>{{ column }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const usersReportTrans = {
|
||||
undefined_member: `{{ trans('visiosoft.module.profile::field.undefined_member') }}`,
|
||||
};
|
||||
</script>
|
||||
|
||||
{{ asset_add('scripts.js', 'visiosoft.module.profile::assets/js/admin/dashboard/report.js') }}
|
||||
@ -0,0 +1,41 @@
|
||||
<?php namespace Visiosoft\ProfileModule\Http\Controller\Admin;
|
||||
|
||||
use Anomaly\Streams\Platform\Http\Controller\AdminController;
|
||||
use Anomaly\UsersModule\User\Contract\UserRepositoryInterface;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class ReportController extends AdminController
|
||||
{
|
||||
protected $userRepository;
|
||||
|
||||
public function __construct(UserRepositoryInterface $userRepository)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->userRepository = $userRepository;
|
||||
}
|
||||
|
||||
public function latest()
|
||||
{
|
||||
$members = $this->userRepository->newQuery()
|
||||
->selectRaw("DATE_FORMAT(created_at, '%d.%m.%Y %H:%i') as date, CONCAT_WS('', first_name, ' ', last_name) AS member")
|
||||
->where('created_at', '>=', Carbon::today()->subWeek())
|
||||
->get();
|
||||
|
||||
return [
|
||||
'data' => $members
|
||||
];
|
||||
}
|
||||
|
||||
public function login()
|
||||
{
|
||||
$members = $this->userRepository->newQuery()
|
||||
->selectRaw("DATE_FORMAT(last_login_at, '%d.%m.%Y %H:%i') as date, CONCAT_WS('', first_name, ' ', last_name) AS member")
|
||||
->whereNotNull('last_login_at')
|
||||
->where('last_login_at', '>=', Carbon::today()->subWeek())
|
||||
->get();
|
||||
|
||||
return [
|
||||
'data' => $members
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -124,6 +124,10 @@ class ProfileModuleServiceProvider extends AddonServiceProvider
|
||||
|
||||
// CacheController
|
||||
'ajax/get-user-info' => 'Visiosoft\ProfileModule\Http\Controller\CacheController@getUserInfo',
|
||||
|
||||
// Admin ReportController
|
||||
'admin/api/profile/report/latest' => 'Visiosoft\ProfileModule\Http\Controller\Admin\ReportController@latest',
|
||||
'admin/api/profile/report/login' => 'Visiosoft\ProfileModule\Http\Controller\Admin\ReportController@login',
|
||||
];
|
||||
|
||||
protected $aliases = [
|
||||
|
||||
@ -18,4 +18,4 @@ class BroadcastServiceProvider extends ServiceProvider
|
||||
|
||||
require base_path('routes/channels.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,15 +32,15 @@ return [
|
||||
|
||||
'pusher' => [
|
||||
'driver' => 'pusher',
|
||||
'key' => env('PUSHER_APP_KEY', '12345'),
|
||||
'secret' => env('PUSHER_APP_SECRET', '12345'),
|
||||
'app_id' => env('PUSHER_APP_ID', '12345'),
|
||||
'key' => env('PUSHER_APP_KEY'),
|
||||
'secret' => env('PUSHER_APP_SECRET'),
|
||||
'app_id' => env('PUSHER_APP_ID'),
|
||||
'options' => [
|
||||
'cluster' => env('PUSHER_APP_CLUSTER', 'mt1'),
|
||||
'encrypted' => env('BROADCAST_SSL', false),
|
||||
'cluster' => env('PUSHER_APP_CLUSTER'),
|
||||
'encrypted' => true,
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6001,
|
||||
'scheme' => env('BROADCAST_SSL', false) ? 'https' : 'http',
|
||||
'scheme' => 'https',
|
||||
'curl_options' => [
|
||||
CURLOPT_SSL_VERIFYHOST => 0,
|
||||
CURLOPT_SSL_VERIFYPEER => 0,
|
||||
|
||||
@ -13,6 +13,6 @@ use Illuminate\Support\Facades\Broadcast;
|
||||
|
|
||||
*/
|
||||
|
||||
Broadcast::channel('App.Models.User.{id}', function ($user, $id) {
|
||||
Broadcast::channel('Anomaly.UsersModule.User.UserModel.{id}', function ($user, $id) {
|
||||
return (int) $user->id === (int) $id;
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user