소스 검색

Merge branch 'Kotenko' of gitgod/geolook into master

Serge 5 년 전
부모
커밋
d5905650cb

+ 2 - 0
.gitignore

@@ -1,6 +1,8 @@
 /node_modules
 /public/hot
 /public/storage
+/public/images
+/public/packages
 /storage/*.key
 /vendor
 .env

+ 20 - 1
README.md

@@ -53,4 +53,23 @@ $ git push origin фамилия
 Во избежание бардака, давайте сливать будет кто-то один, если никто не возражает - я<br/>
 Пишите в телегу после пуша.<br/>
 
-Не забываем делать git pull origin master для обновления своей ветки в соответствии с master
+Не забываем делать git pull origin master для обновления своей ветки в соответствии с master.<br/>
+Если после пула увидели след изменения, то выполняем соответсвенные комманды:<br/>
+в папке /database/migrations/<br/>
+````
+$ php artisan migrate
+````
+в папке /config/<br/>
+````
+$ php artisan config:cache
+````
+
+файл composer.lock<br/>
+````
+$ php composer install
+$ php artisan config:cache
+````
+файл package-lock.json
+````
+$ npm install
+````

+ 82 - 0
app/Admin/Templates/GeolookTemplate.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Admin\Templates;
+
+use SleepingOwl\Admin\Templates\Template;
+
+class GeolookTemplate extends Template
+{
+    /**
+     * Получение названия текущего шаблона.
+     *
+     * @return string
+     */
+    public function name()
+    {
+        return 'Geolook Admin Template';
+    }
+
+    /**
+     * Версия темы.
+     *
+     * @return string
+     */
+    public function version()
+    {
+        return '1.0.0';
+    }
+
+    /**
+     * URL проекта.
+     *
+     * @return string
+     */
+    public function homepage()
+    {
+        return 'https://proj.geolook.php.a-level.com.ua/';
+    }
+
+    public function initialize()
+    {
+        $this->meta()
+            ->addJs('admin-default', $this->assetPath('js/admin-app.js'))
+            ->addJs('admin-vue-init', $this->assetPath('js/vue.js'))
+            ->addJs('admin-modules-load', $this->assetPath('js/modules.js'))
+            ->addCss('admin-default', $this->assetPath('css/admin-app.css'));
+    }
+
+    /**
+     * @return string
+     */
+    public function getViewNamespace()
+    {
+        return 'sleeping_owl::default';
+    }
+
+    /**
+     * Получение относительного пути �
+     * ранения asset файлов.
+     *
+     * @return string
+     */
+    public function assetDir()
+    {
+        return 'packages/sleepingowl/default';
+    }
+
+    /**
+     * @return string
+     */
+    public function getLogo()
+    {
+        return '<span class="pull-left">Geolook</span>';
+    }
+
+    /**
+     * @return string
+     */
+    public function getLogoMini()
+    {
+        return '<span class="pull-left">G</span>';
+    }
+}

+ 4 - 0
app/Admin/bootstrap.php

@@ -0,0 +1,4 @@
+<?php
+
+// PackageManager::load('admin-default')
+//    ->css('extend', public_path('packages/sleepingowl/default/css/extend.css'));

+ 102 - 0
app/Admin/navigation.php

@@ -0,0 +1,102 @@
+<?php
+
+use SleepingOwl\Admin\Navigation\Page;
+
+// Default check access logic
+// AdminNavigation::setAccessLogic(function(Page $page) {
+// 	   return auth()->user()->isSuperAdmin();
+// });
+//
+// AdminNavigation::addPage(\App\User::class)->setTitle('test')->setPages(function(Page $page) {
+// 	  $page
+//		  ->addPage()
+//	  	  ->setTitle('Dashboard')
+//		  ->setUrl(route('admin.dashboard'))
+//		  ->setPriority(100);
+//
+//	  $page->addPage(\App\User::class);
+// });
+//
+// // or
+//
+// AdminSection::addMenuPage(\App\User::class)
+
+return [
+    [
+        'title' => 'Dashboard',
+        'icon'  => 'fa fa-dashboard',
+        'url'   => route('admin.dashboard'),
+        'priority' => '10'
+    ],
+
+    [
+        'title' => 'Information',
+        'icon'  => 'fa fa-exclamation-circle',
+        'url'   => route('admin.information'),
+    ],
+
+    [
+        'title' => 'Telegram',
+        'icon'  => 'fa fa-telegram',
+        'url'   => route('admin.setting.index'),
+        'priority' => '40'
+    ],
+
+    (new Page(\App\User::class))
+        ->setIcon('fa fa-user')
+        ->setTitle('Users')
+        ->setPriority(20),
+
+    // Examples
+    // [
+    //    'title' => 'Content',
+    //    'pages' => [
+    //
+    //        \App\User::class,
+    //
+    //        // or
+    //
+    //        (new Page(\App\User::class))
+    //            ->setPriority(100)
+    //            ->setIcon('fa fa-user')
+    //            ->setUrl('users')
+    //            ->setAccessLogic(function (Page $page) {
+    //                return auth()->user()->isSuperAdmin();
+    //            }),
+    //
+    //        // or
+    //
+    //        new Page([
+    //            'title'    => 'News',
+    //            'priority' => 200,
+    //            'model'    => \App\News::class
+    //        ]),
+    //
+    //        // or
+    //        (new Page(/* ... */))->setPages(function (Page $page) {
+    //            $page->addPage([
+    //                'title'    => 'Blog',
+    //                'priority' => 100,
+    //                'model'    => \App\Blog::class
+	//		      ));
+    //
+	//		      $page->addPage(\App\Blog::class);
+    //	      }),
+    //
+    //        // or
+    //
+    //        [
+    //            'title'       => 'News',
+    //            'priority'    => 300,
+    //            'accessLogic' => function ($page) {
+    //                return $page->isActive();
+    //		      },
+    //            'pages'       => [
+    //
+    //                // ...
+    //
+    //            ]
+    //        ]
+    //    ]
+    // ]
+];

+ 23 - 0
app/Admin/routes.php

@@ -0,0 +1,23 @@
+<?php
+
+Route::get('', ['as' => 'admin.dashboard', function () {
+	$content = view('admin.dashboard', [
+        'usersCount' => \App\User::count(),
+        'locationsCount' => \App\Location::count()]);
+	return AdminSection::view($content, 'Dashboard');
+}]);
+
+Route::get('information', ['as' => 'admin.information', function () {
+	$content = 'Define your information here.';
+	return AdminSection::view($content, 'Information');
+}]);
+
+Route::namespace('App\Http\Admin\Telegram')->prefix('telegram')->group(function() {
+    Route::get('/', ['as' => 'admin.setting.index', 'uses' => 'SettingController@index']);
+    Route::post('/store', ['as' => 'admin.setting.store', 'uses' => 'SettingController@store']);
+    Route::post('/setwebhook', ['as' => 'admin.setting.setwebhook', 'uses' => 'SettingController@setWebhook']);
+
+    Route::post('/getwebhook', ['as' => 'admin.setting.getwebhookinfo', 'uses' => 'SettingController@getWebhookInfo']);
+
+    Route::get('/test', ['as' => 'admin.test', 'uses' => 'SettingController@test']);
+});

+ 145 - 0
app/Http/Admin/Locations.php

@@ -0,0 +1,145 @@
+<?php
+
+namespace App\Http\Admin;
+
+use AdminColumn;
+use AdminColumnEditable;
+use AdminDisplay;
+use AdminForm;
+use AdminFormElement;
+use AdminSection;
+use App\User;
+use App\Watcher;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Log;
+use SleepingOwl\Admin\Contracts\Display\DisplayInterface;
+use SleepingOwl\Admin\Contracts\Form\FormInterface;
+use SleepingOwl\Admin\Contracts\Initializable;
+use SleepingOwl\Admin\Form\Buttons\Cancel;
+use SleepingOwl\Admin\Form\Buttons\Save;
+use SleepingOwl\Admin\Section;
+
+/**
+ * Class Users
+ *
+ * @property \App\User $model
+ *
+ * @see http://sleepingowladmin.ru/docs/model_configuration_section
+ */
+class Locations extends Section implements Initializable
+{
+    /**
+     * @see http://sleepingowladmin.ru/docs/model_configuration#ограничение-прав-доступа
+     *
+     * @var bool
+     */
+    protected $checkAccess = false;
+    protected $redirect = ['edit' => 'display', 'create' => 'display'];
+
+    /**
+     * @var string
+     */
+    protected $title;
+
+    public function initialize()
+    {
+        $this->creating(function ($config, Model $model) {
+        });
+    }
+
+    /**
+     * @var string
+     */
+    protected $alias;
+
+    /**
+     * @return DisplayInterface
+     */
+    public function onDisplay()
+    {
+        $form = AdminDisplay::datatablesAsync()->setDisplaySearch(true)
+            ->setOrder([[0, 'desc']])
+            ->setHtmlAttribute('class', 'table-primary')
+            ->setColumns(
+                AdminColumn::link('id', '#')->setWidth('30px'),
+                AdminColumnEditable::text('lat', 'lat')->setWidth('100px'),
+                AdminColumnEditable::text('lng', 'lng')->setWidth('100px'),
+                AdminColumnEditable::text('created_at', 'Date')->setWidth('100px')
+            )->paginate(20);
+
+        $filters = request()->get('payload', []);
+        Log::info($filters);
+        if (! empty($filters['user_id'])) {
+            $userId = $filters['user_id'];
+            $form->setApply(function ($query) use ($userId) {
+                $query->where('user_id', $userId);
+            });
+        }
+
+        return $form;
+    }
+
+    /**
+     * @param int $id
+     *
+     * @return FormInterface
+     */
+    public function onEdit($id)
+    {
+        $users = [];
+        foreach (User::all() as $user) {
+            $users[$user->id] = $user['name'];
+        }
+
+        $formElements = [
+            AdminFormElement::select('user_id', 'User', $users),
+            AdminFormElement::columns()
+                ->addColumn(function () {
+                    return [
+                        AdminFormElement::text('lat', 'lat')
+                    ];
+                })
+                ->addColumn(function () {
+                    return [
+                        AdminFormElement::text('lng', 'lng')
+                    ];
+                })
+        ];
+
+        $form = AdminForm::panel();
+
+        $form->addBody($formElements);
+
+        $form->getButtons()->setButtons([
+            'save' => new Save(),
+            'cancel' => new Cancel(),
+        ]);
+
+        return $form;
+    }
+
+    /**
+     * @return FormInterface
+     */
+    public function onCreate()
+    {
+        return $this->onEdit(null);
+    }
+
+    /**
+     * @return void
+     */
+    public function onDelete($id)
+    {
+        // remove if unused
+    }
+
+    /**
+     * @return void
+     */
+    public function onRestore($id)
+    {
+        // remove if unused
+    }
+}

+ 51 - 0
app/Http/Admin/Telegram/SettingController.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace App\Http\Admin\Telegram;
+
+use AdminSection;
+use App\Setting;
+use GuzzleHttp\Client;
+use Illuminate\Http\Request;
+use App\Http\Controllers\Controller;
+use Psr\Log\NullLogger;
+use Telegram\Bot\Api;
+
+class SettingController extends Controller
+{
+    public function index(){
+        return AdminSection::view(view('admin.telegram', Setting::getSettings()));
+    }
+
+    public function store(Request $request){
+        Setting::where('key', '!=', NULL)->delete();
+
+        foreach ($request->except('_token') as $key => $value){
+            $setting = new Setting;
+            $setting->key = $key;
+            $setting->value = $request->$key;
+            $setting->save();
+        }
+
+        return redirect()->route('admin.setting.index');
+    }
+
+    public function setWebhook(Request $request){
+        $result = $this->sendTelegramData($request->url ? 'setWebhook' : 'deleteWebhook', [
+            'query' => ['url' => $request->url . '/' . \Telegram::getAccessToken()]
+        ]);
+
+        return redirect()->route('admin.setting.index')->with('status', $result);
+    }
+
+    public function getWebhookInfo(){
+
+        $result = $this->sendTelegramData('getWebhookInfo');
+        return redirect()->route('admin.setting.index')->with('status', $result);
+    }
+
+    public function sendTelegramData ($rout = '', $params = [], $method = 'POST'){
+        $client = new Client( ['base_uri' => 'https://api.telegram.org/bot' . \Telegram::getAccessToken() . '/'] );
+        $result = $client->request( $method, $rout, $params);
+        return (string) $result->getBody();
+    }
+}

+ 141 - 0
app/Http/Admin/Users.php

@@ -0,0 +1,141 @@
+<?php
+
+namespace App\Http\Admin;
+
+use AdminColumn;
+use AdminColumnEditable;
+use AdminDisplay;
+use AdminForm;
+use AdminFormElement;
+use AdminSection;
+use App\Location;
+use App\User;
+use App\Watcher;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Log;
+use SleepingOwl\Admin\Contracts\Display\DisplayInterface;
+use SleepingOwl\Admin\Contracts\Form\FormInterface;
+use SleepingOwl\Admin\Contracts\Initializable;
+use SleepingOwl\Admin\Form\Buttons\Cancel;
+use SleepingOwl\Admin\Form\Buttons\Save;
+use SleepingOwl\Admin\Form\FormElements;
+use SleepingOwl\Admin\Section;
+
+/**
+ * Class Users
+ *
+ * @property \App\User $model
+ *
+ * @see http://sleepingowladmin.ru/docs/model_configuration_section
+ */
+class Users extends Section implements Initializable
+{
+    /**
+     * @see http://sleepingowladmin.ru/docs/model_configuration#ограничение-прав-доступа
+     *
+     * @var bool
+     */
+    protected $checkAccess = false;
+    protected $redirect = ['edit' => 'display', 'create' => 'display'];
+    //protected $model = User::class;
+
+    /**
+     * @var string
+     */
+    protected $title;
+
+    public function initialize()
+    {
+        $this->creating(function ($config, Model $model) {
+        });
+    }
+
+    /**
+     * @var string
+     */
+    protected $alias;
+
+    /**
+     * @return DisplayInterface
+     */
+    public function onDisplay()
+    {
+        $form = AdminDisplay::datatablesAsync()->setDisplaySearch(true)
+            ->setOrder([[0, 'desc']])
+            ->setHtmlAttribute('class', 'table-primary')
+            ->setColumns(
+                AdminColumn::link('id', '#')->setWidth('30px'),
+                AdminColumnEditable::text('name', 'Name')->setWidth('100px'),
+                AdminColumn::link('email', 'Email')->setWidth('100px')
+            )->paginate(20);
+
+        return $form;
+    }
+
+    /**
+     * @param int $id
+     *
+     * @return FormInterface
+     */
+    public function onEdit($id)
+    {
+        function product($id) {
+            $formElement = [];
+
+            if($id != null){
+                $category = User::find($id)->id;
+                $formElement[] = AdminSection::getModel(Location::class)->fireDisplay(['user_id' => $category]);
+            }
+
+            return $formElement;
+        };
+
+        $formElements = [
+            AdminFormElement::text('name', 'Name')->required(),
+            AdminFormElement::text('email', 'Name')->required(),
+        ];
+
+        $tabs = AdminDisplay::tabbed([
+            'General' => new FormElements($formElements),
+            'Locations' => new FormElements(product($id)),
+        ]);
+
+        $context = empty($id) ? $formElements : $tabs;
+
+        $form = AdminForm::panel();
+
+        $form->addBody($context);
+
+        $form->getButtons()->setButtons([
+            'save' => new Save(),
+            'cancel' => new Cancel(),
+        ]);
+
+        return $form;
+    }
+
+    /**
+     * @return FormInterface
+     */
+    public function onCreate()
+    {
+        return $this->onEdit(null);
+    }
+
+    /**
+     * @return void
+     */
+    public function onDelete($id)
+    {
+        // remove if unused
+    }
+
+    /**
+     * @return void
+     */
+    public function onRestore($id)
+    {
+        // remove if unused
+    }
+}

+ 34 - 0
app/Providers/AdminSectionsServiceProvider.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Providers;
+
+use App\Http\Admin\Locations;
+use App\Http\Admin\Users;
+use App\Location;
+use App\User;
+use SleepingOwl\Admin\Providers\AdminSectionsServiceProvider as ServiceProvider;
+
+class AdminSectionsServiceProvider extends ServiceProvider
+{
+
+    /**
+     * @var array
+     */
+    protected $sections = [
+        User::class => Users::class,
+        Location::class => Locations::class
+    ];
+
+    /**
+     * Register sections.
+     *
+     * @param \SleepingOwl\Admin\Admin $admin
+     * @return void
+     */
+    public function boot(\SleepingOwl\Admin\Admin $admin)
+    {
+    	//
+
+        parent::boot($admin);
+    }
+}

+ 20 - 0
app/Setting.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Setting extends Model
+{
+    public $timestamps = false;
+
+    public static function getSettings($key = null){
+        $settings = $key ? self::where('key', $key)->first() : self::get();
+        $collect = collect();
+        foreach ($settings as $setting){
+            $collect->put($setting->key, $setting->value);
+        }
+
+        return $collect;
+    }
+}

+ 53 - 0
app/TCommands/TestCommand.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace App\TCommands;
+
+use Illuminate\Support\Facades\Log;
+use Telegram\Bot\Actions;
+use Telegram\Bot\Commands\Command;
+
+/**
+ * Class TestCommand.
+ */
+class TestCommand extends Command
+{
+    /**
+     * @var string Command Name
+     */
+    protected $name = 'test';
+
+    /**
+     * @var array Command Aliases
+     */
+    protected $aliases = ['listcommands'];
+
+    /**
+     * @var string Command Description
+     */
+    protected $description = 'Проверка';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handle($arguments)
+    {
+        Log::info($arguments);
+        $text = 'Привет';
+        $this->replyWithMessage(compact('text'));
+
+        $this->replyWithChatAction(['action' => Actions::TYPING]);
+
+        $telegram_user = \Telegram::getWebhookUpdates()['message'];
+//        Log::info([$telegram_user]);
+//
+        $text = sprintf('%s: %s'.PHP_EOL, 'Ваш номер чата', $telegram_user['from']['id']);
+        if (isset($telegram_user['from']['username'])){
+            $text .= sprintf('%s: %s'.PHP_EOL, 'Ваше имя пользователя в телеграм', $telegram_user['from']['username']);
+        }
+//        Log::info($text);
+        $this->replyWithMessage(compact('text'));
+
+        $updateId = \Telegram::getWebhookUpdates()['update_id']+1;
+        \Telegram::getWebhookUpdates(['offset'=>$updateId]);
+    }
+}

+ 3 - 1
composer.json

@@ -10,8 +10,10 @@
     "require": {
         "php": "^7.1.3",
         "fideloper/proxy": "^4.0",
+        "irazasyed/telegram-bot-sdk": "2.2.0",
         "laravel/framework": "5.7.*",
-        "laravel/tinker": "^1.0"
+        "laravel/tinker": "^1.0",
+        "laravelrus/sleepingowl": "5.6.6"
     },
     "require-dev": {
         "barryvdh/laravel-ide-helper": "^2.6",

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2056 - 1432
composer.lock


+ 7 - 0
config/app.php

@@ -162,9 +162,15 @@ return [
         Illuminate\Validation\ValidationServiceProvider::class,
         Illuminate\View\ViewServiceProvider::class,
 
+        /*
+         * SleepingOwl Service Provider
+         */
+        SleepingOwl\Admin\Providers\SleepingOwlServiceProvider::class,
+
         /*
          * Package Service Providers...
          */
+        Telegram\Bot\Laravel\TelegramServiceProvider::class,
 
         /*
          * Application Service Providers...
@@ -223,6 +229,7 @@ return [
         'URL' => Illuminate\Support\Facades\URL::class,
         'Validator' => Illuminate\Support\Facades\Validator::class,
         'View' => Illuminate\Support\Facades\View::class,
+        'Telegram'  => Telegram\Bot\Laravel\Facades\Telegram::class,
 
     ],
 

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 241 - 0
config/sleeping_owl.php


+ 61 - 0
config/telegram.php

@@ -0,0 +1,61 @@
+<?php
+
+return [
+    /*
+    |--------------------------------------------------------------------------
+    | Telegram Bot API Access Token [REQUIRED]
+    |--------------------------------------------------------------------------
+    |
+    | Your Telegram's Bot Access Token.
+    | Example: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
+    |
+    | Refer for more details:
+    | https://core.telegram.org/bots#botfather
+    |
+    */
+    'bot_token' => env('TELEGRAM_BOT_TOKEN', '869244226:AAG1K-ku_c7q-8TgaaEKR9k14kEWZ7AqfCs'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Asynchronous Requests [Optional]
+    |--------------------------------------------------------------------------
+    |
+    | When set to True, All the requests would be made non-blocking (Async).
+    |
+    | Default: false
+    | Possible Values: (Boolean) "true" OR "false"
+    |
+    */
+    'async_requests' => env('TELEGRAM_ASYNC_REQUESTS', false),
+
+    /*
+    |--------------------------------------------------------------------------
+    | HTTP Client Handler [Optional]
+    |--------------------------------------------------------------------------
+    |
+    | If you'd like to use a custom HTTP Client Handler.
+    | Should be an instance of \Telegram\Bot\HttpClients\HttpClientInterface
+    |
+    | Default: GuzzlePHP
+    |
+    */
+    'http_client_handler' => null,
+
+    /*
+    |--------------------------------------------------------------------------
+    | Register Telegram Commands [Optional]
+    |--------------------------------------------------------------------------
+    |
+    | If you'd like to use the SDK's built in command handler system,
+    | You can register all the commands here.
+    |
+    | The command class should extend the \Telegram\Bot\Commands\Command class.
+    |
+    | Default: The SDK registers, a help command which when a user sends /help
+    | will respond with a list of available commands and description.
+    |
+    */
+    'commands' => [
+        Telegram\Bot\Commands\HelpCommand::class,
+    ],
+];

+ 3 - 2
database/factories/LocationFactory.php

@@ -21,8 +21,9 @@ $factory->define(Location::class, function (Faker $faker) {
     return [
         'lat' => array_random($latArray),
         'lng' => array_random($lngArray),
-	'created_at' => $time,
-	'updated_at' => $time,
+        'created_at' => Carbon::now()->subDays(rand(1, 10))->subHours(rand(8, -8)),
+	    'created_at' => $time,
+	    'updated_at' => $time,
         'user_id' => null,//
     ];
 });

+ 40 - 0
database/migrations/2019_03_18_092742_create_settings_table.php

@@ -0,0 +1,40 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+use App\Setting;
+
+class CreateSettingsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('settings', function (Blueprint $table) {
+            $table->string('key', 40)->index()->unique();
+            $table->mediumText('value')->nullable();
+            $table->boolean('serialized')->default(0);
+        });
+
+        $entety = new Setting();
+        $entety->key = 'url_callback_bot';
+        $entety->value = 'http://localhost/tbot';
+        $entety->serialized = 0;
+        $entety->save();
+
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('settings');
+    }
+}

+ 31 - 0
resources/views/admin/dashboard.blade.php

@@ -0,0 +1,31 @@
+<div class="row">
+    <div class="col-md-4 col-sm-6 col-xs-12">
+        <div class="info-box">
+            <a href="admin/users">
+                <span class="info-box-icon bg-aqua">
+                    <i class="fa fa-user"></i>
+                </span>
+            </a>
+            <div class="info-box-content">
+                <span class="info-box-text">Users</span>
+                    <span class="info-box-number">{{ $usersCount }}<small></small>
+                </span>
+            </div>
+        </div>
+    </div>
+
+    <div class="col-md-4 col-sm-6 col-xs-12">
+        <div class="info-box">
+            <a href="admin/watchers">
+                <span class="info-box-icon bg-green">
+                    <i class="fa fa-globe"></i>
+                </span>
+            </a>
+            <div class="info-box-content">
+                <span class="info-box-text">Locations</span>
+                <span class="info-box-number">{{ $locationsCount }}<small></small>
+                </span>
+            </div>
+        </div>
+    </div>
+</div>

+ 43 - 0
resources/views/admin/telegram.blade.php

@@ -0,0 +1,43 @@
+<div class="container">
+    @if(Session::has('status'))
+        <div class="alert alert-info">
+            <span>{{ Session::get('status') }}</span>
+        </div>
+    @endif
+
+    <form action="{{ route('admin.setting.store') }}" method="post">
+        {{--{{ scrf_field() }}--}}
+        @csrf
+        <div class="form-group">
+            <h1>URL callback для Telegram</h1>
+            <div class="input-group">
+                <div class="input-group-btn">
+                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true"
+                            aria-expanded="false">Действие<span class="caret"></span></button>
+                    <ul class="dropdown-menu">
+                        <li>
+                            <a href="#" onclick="document.getElementById('url_callback_bot').value = '{{ url('/tbot') }}'">Вставить URL</a>
+                        </li>
+                        <li>
+                            <a href="#" onclick="event.preventDefault(); document.getElementById('setwebhook').submit()">Отправить URL</a>
+                        </li>
+                        <li>
+                            <a href="#" onclick="event.preventDefault(); document.getElementById('getwebhookinfo').submit()">Получить информацию</a>
+                        </li>
+                    </ul>
+                </div>
+                <input type="url" class="form-control" id="url_callback_bot" name="url_callback_bot" value="{{ isset($url_callback_bot) ?$url_callback_bot: '' }}">
+            </div>
+        </div>
+        <button class="btn btn-primary" type="submit">Сохранить</button>
+    </form>
+
+    <form id="setwebhook" action="{{ route('admin.setting.setwebhook') }}" method="POST" style="display: none">
+        @csrf
+        <input type="hidden" name="url" value="{{ isset($url_callback_bot) ?$url_callback_bot: '' }}">
+    </form>
+
+    <form id="getwebhookinfo" action="{{ route('admin.setting.getwebhookinfo') }}" method="POST" style="display: none">
+        @csrf
+    </form>
+</div>

+ 3 - 0
routes/web.php

@@ -23,3 +23,6 @@ Route::get('/user', 'UserController@index')->name('all.positions');
 Route::get('/user/{id}', 'UserController@show')->where('id', '[0-9]+')->name('user.position');
 Route::get('/user/{id}/last', 'UserController@showLast')->where('id', '[0-9]+')->name('last.position');
 
+Route::post('/tbot/'.Telegram::getAccessToken(), function(){
+    Telegram::commandsHandler(true);
+});