diff --git a/app/Classes/Meta.php b/app/Classes/Meta.php new file mode 100644 index 0000000..6803196 --- /dev/null +++ b/app/Classes/Meta.php @@ -0,0 +1,260 @@ +0, + "success"=>1, + "fail"=>2 + ); + private $metaData; + private $url; + private $html; + private $status; + private $meta; + + /** + * __construct + * + * Require the url of the webpage for meta data extraction + * + * @access public + * @param string $url + */ + public function __construct($url) { + $this->url = $url; + $this->metaData = new \StdClass; + $this->metaData->title = ""; + $this->metaData->description = ""; + $this->metaData->keywords = ""; + $this->metaData->image = ""; + $this->initialized(); + } + + /** + * parse + * + * Parse the meta data from the given url and populate data member $metaData + * + * @access public + * @return integer + */ + public function parse() { + // load HTML as DOMDocument object for parsing + $this->html = new \DOMDocument; + libxml_use_internal_errors(true); + $this->html->loadHTML(file_get_contents($this->url)); + + // php built-in get_meta_tags() only read those with name "title", "description" and so on + // so I wrote my own version supporting twitter:title, og:title, etc. + $this->meta = $this->my_get_meta_tags($this->url); + + $this->success(); // assume successful + + // possible to add more method such as getAuthor() + $this->getTitle(); + $this->getDescription(); + $this->getKeywords(); + $this->getImage(); + + return $this->status; + } + + + /** + * finalize + * + * Export the meta data parsed + * + * @access public + * @return StdClass + */ + public function finalize() { + $tmp = new \StdClass; + $tmp->url = $this->url; + $tmp->title = $this->metaData->title; + $tmp->description = $this->metaData->description; + $tmp->image = $this->metaData->image; + $tmp->status = $this->status; + $tmp->keywords = $this->metaData->keywords; + return $tmp; + } + + /** + * my_get_meta_tags + * + * Require the url to be parsed, read every meta tags found + * + * @access private + * @param string $url + * @return array + */ + private function my_get_meta_tags($url) { + $metatags = $this->html->getElementsByTagName("meta"); + $tmeta = array(); + for ($i=0; $i<$metatags->length; ++$i) { + $item = $metatags->item($i); + $name = $item->getAttribute('name'); + + if (empty($name)) { + // og meta tags, or twitter meta tags + $tmeta[$item->getAttribute('property')] = $item->getAttribute('content'); + } + else { + // conventional meta tags + $tmeta[$name] = $item->getAttribute('content'); + } + } + return $tmeta; + } + + /** + * initizlized + * + * Set the state of the object to be initizlied + * + * @access private + */ + private function initialized() { + $this->status = self::$STATUS["initialized"]; + } + + /** + * success + * + * Set the state of the object to be successful + * + * @access private + */ + private function success() { + $this->status = self::$STATUS["success"]; + } + + /** + * fail + * + * Set the state of the object to be failed + * + * @access private + */ + private function fail() { + $this->status = self::$STATUS["fail"]; + } + + /** + * getTitle + * + * Read meta title based on priorities of the tag name/property, + * fallback to reading and <h1> if meta title not present + * + * @access private + */ + private function getTitle() { + if (isset($this->meta["og:title"])) { + $this->metaData->title = $this->meta["og:title"]; + return; + } + + if (isset($this->meta["twitter:title"])) { + $this->metaData->title = $this->meta["twitter:title"]; + return; + } + + if (isset($this->meta["title"])) { + $this->metaData->title = $this->meta["title"]; + return; + } + + $title = $this->html->getElementsByTagName("title") or $title = $this->html->getElementsByTagName("h1"); + // taking either the title or h1 tag + if (!$title->length) { + // if no h1 tag, nothing good enough to be the site title + $this->fail(); + return; + } + else { + $this->metaData->title = ($title->length) ? $title->item(0)->nodeValue : ""; + } + } + + /** + * getDescription + * + * Read meta description based on priorities of the tag name/property. + * No fallback, it doesn't read anything except for the meta tag + * + * @access private + */ + private function getDescription() { + if (isset($this->meta["og:description"])) { + $this->metaData->description = $this->meta["og:description"]; + return; + } + + if (isset($this->meta["twitter:description"])) { + $this->metaData->description = $this->meta["twitter:description"]; + return; + } + + if (isset($this->meta["description"])) { + $this->metaData->description = $this->meta["description"]; + return; + } + + $this->fail(); + return; + } + + + private function getKeywords() { + if (isset($this->meta["og:keywords"])) { + $this->metaData->keywords = $this->meta["og:keywords"]; + return; + } + + if (isset($this->meta["twitter:keywords"])) { + $this->metaData->keywords = $this->meta["twitter:description"]; + return; + } + + if (isset($this->meta["keywords"])) { + $this->metaData->keywords = $this->meta["keywords"]; + return; + } + + $this->fail(); + return; + } + + + /** + * getImage + * + * Read meta image url based on priorities of the tag name/property. + * No fallback, it doesn't read anything except for the meta tag + * + * @access private + */ + private function getImage() { + if (isset($this->meta["og:image"])) { + $this->metaData->image = $this->meta["og:image"]; + return; + } + + if (isset($this->meta["twitter:image"])) { + $this->metaData->image = $this->meta["twitter:image"]; + return; + } + + if (isset($this->meta["image"])) { + $this->metaData->image = $this->meta["image"]; + return; + } + + $this->fail(); + } +} diff --git a/app/Http/Controllers/Admin/CompanyController.php b/app/Http/Controllers/Admin/CompanyController.php index 0533a04..7faacad 100644 --- a/app/Http/Controllers/Admin/CompanyController.php +++ b/app/Http/Controllers/Admin/CompanyController.php @@ -3,11 +3,16 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; +use App\Http\Requests\PagesRequest; +use App\Http\Requests\SEORequest; use App\Models\Employer; use App\Models\employers_main; +use App\Models\header_footer; use App\Models\Job_title; use App\Models\job_titles_main; use App\Models\pages; +use App\Models\reclame; +use App\Models\SEO; use Illuminate\Http\Request; class CompanyController extends Controller @@ -17,11 +22,6 @@ class CompanyController extends Controller return; } - // кабинет - редактор шапки-футера сайта - public function editblocks() { - return; - } - // кабинет - редактор должности на главной public function job_titles_main(Request $request) { if ($request->ajax()) { @@ -40,6 +40,12 @@ class CompanyController extends Controller } } + // кабинет - редактор шапки-футера сайта + public function editblocks() { + $header_footer = header_footer::query()->OrderBy('name')->paginate(15); + return view('admin.editbloks.index', compact('header_footer')); + } + // кабинет - редактор работодатели на главной public function employers_main(Request $request) { if ($request->ajax()) { @@ -58,11 +64,36 @@ class CompanyController extends Controller } } - // кабинет - редактор seo-сайта + //////////// кабинет - редактор seo-сайта ///////////////////////////// public function editor_seo() { - return; + $pages = SEO::query()->OrderBy('url')->paginate(15); + return view('admin.seo.index', compact('pages')); } + public function editor_seo_add() { + return view('admin.seo.add'); + } + + public function editor_seo_store(SEORequest $request) { + SEO::create($request->all()); + return redirect()->route('admin.editor-seo'); + } + + public function editor_seo_edit(SEO $page) { + return view('admin.seo.edit', compact('page')); + } + + public function editor_seo_update(SEORequest $request, SEO $page) { + $page->update($request->all()); + return redirect()->route('admin.editor-seo'); + } + + public function editor_seo_destroy(SEO $page) { + $page->delete(); + return redirect()->route('admin.editor-seo'); + } + /////////////////////////////////////////////////////////////////////// + /////////// кабинет - редактор страниц //////////////////////////////// public function editor_pages() { $pages = pages::query()->OrderBy('name')->paginate(15); @@ -73,25 +104,29 @@ class CompanyController extends Controller return view('admin.pages.add'); } - public function editor_pages_store(Request $request) { - return; + public function editor_pages_store(PagesRequest $request) { + pages::create($request->all()); + return redirect()->route('admin.editor-pages'); } public function editor_pages_edit(pages $page) { return view('admin.pages.edit', compact('page')); } - public function editor_pages_update(Request $request, pages $page) { - return; + public function editor_pages_update(PagesRequest $request, pages $page) { + $page->update($request->all()); + return redirect()->route('admin.editor-pages'); } public function editor_pages_destroy(pages $page) { - return; + $page->delete(); + return redirect()->route('admin.editor-pages'); } /////////////////////////////////////////////////////////////////// // кабинет - реклама сайта public function reclames() { - return; + $reclames = reclame::query()->OrderBy('title')->paginate(15); + return view('admin.reclames.index', compact('reclames')); } } diff --git a/app/Http/Controllers/CKEditorController.php b/app/Http/Controllers/CKEditorController.php new file mode 100644 index 0000000..d98d01e --- /dev/null +++ b/app/Http/Controllers/CKEditorController.php @@ -0,0 +1,26 @@ +<?php + +namespace App\Http\Controllers; + +use Illuminate\Http\Request; + +class CKEditorController extends Controller +{ + public function upload(Request $request) + { + if($request->hasFile('upload')) { + $originName = $request->file('upload')->getClientOriginalName(); + $fileName = pathinfo($originName, PATHINFO_FILENAME); + $extension = $request->file('upload')->getClientOriginalExtension(); + $fileName = $fileName.'_'.time().'.'.$extension; + $request->file('upload')->move(public_path('images'), $fileName); + $CKEditorFuncNum = $request->input('CKEditorFuncNum'); + $url = asset('images/'.$fileName); + $msg = 'Image successfully uploaded'; + $response = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>"; + + @header('Content-type: text/html; charset=utf-8'); + echo $response; + } + } +} diff --git a/app/Http/Controllers/PagesController.php b/app/Http/Controllers/PagesController.php index 2ac9d42..d771353 100644 --- a/app/Http/Controllers/PagesController.php +++ b/app/Http/Controllers/PagesController.php @@ -2,11 +2,13 @@ namespace App\Http\Controllers; +use App\Models\pages; use Illuminate\Http\Request; class PagesController extends Controller { - public function pages(string $slug) { - return; + public function pages(pages $pages) { + $page = pages::query()->where('slug', $pages->slug)->first(); + print_r($page); } } diff --git a/app/Http/Requests/PagesRequest.php b/app/Http/Requests/PagesRequest.php index 5867331..2170818 100644 --- a/app/Http/Requests/PagesRequest.php +++ b/app/Http/Requests/PagesRequest.php @@ -13,7 +13,7 @@ class PagesRequest extends FormRequest */ public function authorize() { - return false; + return true; } /** @@ -23,8 +23,67 @@ class PagesRequest extends FormRequest */ public function rules() { + $unique = 'unique:pages,slug'; + if (in_array($this->route()->getName(), ['admin.update-page'])) { + // получаем модель Pages через маршрут admin/editor-pages/edit/{page} + $model = $this->route('page'); + /* + * Проверка на уникальность slug, исключая этот пост по идентификатору: + * 1. posts - таблица базы данных, где проверяется уникальность + * 2. slug - имя колонки, уникальность значения которой проверяется + * 3. значение по которому из проверки исключается запись таблицы БД + * 4. поле, по которому из проверки исключается запись таблицы БД + * Для проверки будет использован такой SQL-запрос к базе данных: + * SELECT COUNT(*) FROM `pages` WHERE `slug` = '...' AND `id` <> 17 + */ + $unique = 'unique:pages,slug,'.$model->id.',id'; + } + return [ - // + 'name' => [ + 'required', + 'string', + 'min:3', + 'max:255', + ], + 'slug' => [ + 'required', + 'max:255', + $unique, + 'regex:~^[-_a-z0-9]+$~i', + ], + 'anons' => [ + 'required', + 'min:500', + ], + 'text' => [ + 'required', + 'min:500', + ], + 'image' => [ + 'mimes:jpeg,jpg,png', + 'max:15000' + ], + ]; + } + + public function messages() { + return [ + 'required' => 'Поле :attribute обязательно для ввода', + 'unique' => 'Поле :attribute должно быть уникальным', + 'mimes' => 'Допускаются файлы только с расширением jpeg,jpg,png', + 'min' => [ + 'string' => 'Поле «:attribute» должно быть не меньше :min символов', + 'integer' => 'Поле «:attribute» должно быть :min или больше', + 'file' => 'Файл «:attribute» должен быть не меньше :min Кбайт' + ], + + 'max' => [ + 'string' => 'Поле «:attribute» должно быть не больше :max символов', + 'integer' => 'Поле «:attribute» должно быть :max или меньше', + 'file' => 'Файл «:attribute» должен быть не больше :max Кбайт' + ], + ]; } } diff --git a/app/Http/Requests/SEORequest.php b/app/Http/Requests/SEORequest.php new file mode 100644 index 0000000..afea372 --- /dev/null +++ b/app/Http/Requests/SEORequest.php @@ -0,0 +1,30 @@ +<?php + +namespace App\Http\Requests; + +use Illuminate\Foundation\Http\FormRequest; + +class SEORequest extends FormRequest +{ + /** + * Determine if the user is authorized to make this request. + * + * @return bool + */ + public function authorize() + { + return false; + } + + /** + * Get the validation rules that apply to the request. + * + * @return array<string, mixed> + */ + public function rules() + { + return [ + // + ]; + } +} diff --git a/app/Models/pages.php b/app/Models/pages.php index 34fd8de..420228d 100644 --- a/app/Models/pages.php +++ b/app/Models/pages.php @@ -8,4 +8,13 @@ use Illuminate\Database\Eloquent\Model; class pages extends Model { use HasFactory; + + protected $fillable = [ + 'name', + 'slug', + 'text', + 'anons', + 'author', + 'image', + ]; } diff --git a/resources/views/admin/editbloks/index.blade.php b/resources/views/admin/editbloks/index.blade.php new file mode 100644 index 0000000..0b80204 --- /dev/null +++ b/resources/views/admin/editbloks/index.blade.php @@ -0,0 +1,95 @@ +@extends('layout.admin', ['title' => 'Админка - Редактор шапки-футера сайта']) + +@section('script') + +@endsection + +@section('search') + <!--<div class="absolute inset-y-0 flex items-center pl-2"> + <svg + class="w-4 h-4" + aria-hidden="true" + fill="currentColor" + viewBox="0 0 20 20" + > + <path + fill-rule="evenodd" + d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" + clip-rule="evenodd" + ></path> + </svg> + </div> + <form action="" method="POST"> + <div style="float:left;"><input + class="w-full pl-8 pr-2 text-sm text-gray-700 placeholder-gray-600 bg-gray-100 border-0 rounded-md dark:placeholder-gray-500 dark:focus:shadow-outline-gray dark:focus:placeholder-gray-600 dark:bg-gray-700 dark:text-gray-200 focus:placeholder-gray-500 focus:bg-white focus:border-purple-300 focus:outline-none focus:shadow-outline-purple form-input" + style="width: 400px" + type="text" + placeholder="Искать..." + aria-label="Search" + /></div> + <div style="float: left"> + <button type="submit" class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">Искать</button> + </div> + </form>--> +@endsection + +@section('content') + + <a href="{{ route('admin.add-seo') }}" style="width: 145px" class="px-3 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"> + Добавить опцию + </a> + <br> + <div class="w-full overflow-hidden rounded-lg shadow-xs" id="ajax_block"> + + <div class="w-full overflow-x-auto"> + <table class="w-full whitespace-no-wrap"> + <thead> + <tr + class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800" + > + <th class="px-4 py-3">№</th> + <th class="px-4 py-3">Название</th> + <th class="px-4 py-3">Ссылка</th> + <th class="px-4 py-3">Категория</th> + <th class="px-4 py-3">Шапка</th> + <th class="px-4 py-3">Дата создания</th> + <th class="px-4 py-3">Редактировать</th> + </tr> + </thead> + <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> + @foreach($header_footer as $page) + <tr class="text-gray-700 dark:text-gray-400"> + <td class="px-4 py-3"> + {{$page->id}} + </td> + <td class="px-4 py-3"> + {{$page->name}} + </td> + <td class="px-4 py-3"> + {{$page->link}} + </td> + <td class="px-4 py-3"> + {{$page->category}} ({{$page->code_id}}) + </td> + <td class="px-4 py-3"> + {{$page->created_at}} + </td> + <td class="px-4 py-3 text-sm_"> + <form action="{{ route('admin.delete-seo', ['page' => $page->id]) }}" method="POST"> + <a href="{{ route('admin.edit-seo', ['page' => $page->id]) }}">Изменить</a> | + @csrf + @method('DELETE') + <input class="btn btn-danger" type="submit" value="Удалить"/> + </form> + </td> + </tr> + @endforeach + </tbody> + </table> + </div> + + <div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"> + <?=$header_footer->appends($_GET)->links('admin.pagginate'); ?> + </div> + </div> +@endsection diff --git a/resources/views/admin/pages/add.blade.php b/resources/views/admin/pages/add.blade.php index 5a5247a..2de3c22 100644 --- a/resources/views/admin/pages/add.blade.php +++ b/resources/views/admin/pages/add.blade.php @@ -1,7 +1,7 @@ @extends('layout.admin', ['title' => 'Админка - Добавление страницы']) @section('content') - <form method="POST" action="{{ route('admin.add-page-store') }}"> + <form method="POST" action="{{ route('admin.add-page-store') }}" enctype="multipart/form-data"> @include('admin.pages.form') </form> @endsection diff --git a/resources/views/admin/pages/edit.blade.php b/resources/views/admin/pages/edit.blade.php index 753c3e1..02b4069 100644 --- a/resources/views/admin/pages/edit.blade.php +++ b/resources/views/admin/pages/edit.blade.php @@ -1,7 +1,7 @@ @extends('layout.admin', ['title' => 'Админка - Редактирование страницы']) @section('content') - <form method="POST" action="{{ route('admin.update-page', ['page' => $page->id]) }}"> + <form method="POST" action="{{ route('admin.update-page', ['page' => $page->id]) }}" enctype="multipart/form-data"> @include('admin.pages.form') </form> @endsection diff --git a/resources/views/admin/pages/form.blade.php b/resources/views/admin/pages/form.blade.php index 3d1b9ea..cb73ab2 100644 --- a/resources/views/admin/pages/form.blade.php +++ b/resources/views/admin/pages/form.blade.php @@ -4,6 +4,56 @@ @method('PUT') @endisset +<script src="//cdn.ckeditor.com/4.14.0/standard/ckeditor.js"></script> +<script> + CKEDITOR.replace( 'anons'); + CKEDITOR.replace( 'text', { + filebrowserUploadUrl: "{{route('ckeditor.image-upload', ['_token' => csrf_token() ])}}", + filebrowserUploadMethod: 'form' + }); +</script> +<script> + function translit(word){ + var answer = ''; + var converter = { + 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', + 'е': 'e', 'ё': 'e', 'ж': 'zh', 'з': 'z', 'и': 'i', + 'й': 'y', 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', + 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', + 'у': 'u', 'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', + 'ш': 'sh', 'щ': 'sch', 'ь': '', 'ы': 'y', 'ъ': '', + 'э': 'e', 'ю': 'yu', 'я': 'ya', + + 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', + 'Е': 'E', 'Ё': 'E', 'Ж': 'Zh', 'З': 'Z', 'И': 'I', + 'Й': 'Y', 'К': 'K', 'Л': 'L', 'М': 'M', 'Н': 'N', + 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', + 'У': 'U', 'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', + 'Ш': 'Sh', 'Щ': 'Sch', 'Ь': '', 'Ы': 'Y', 'Ъ': '', + 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya', ' ': '-' + }; + + for (var i = 0; i < word.length; ++i ) { + if (converter[word[i]] == undefined){ + answer += word[i]; + } else { + answer += converter[word[i]]; + } + } + + return answer; + } + + window.addEventListener("DOMContentLoaded", (event) => { + let title = document.querySelector('#name'); + let text = document.querySelector('#slug'); + + title.addEventListener('input', function() { + text.value = translit(this.value); + }); + }); + +</script> <div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800"> <label class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800"> @@ -69,8 +119,9 @@ </label><br> <label class="block text-sm"> - <input type="file" class="form-control-file" name="image" accept="image/png, image/jpeg"> - </label> + <span class="text-gray-700 dark:text-gray-400">Картинка</span> + <input type="file" class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input" id="image" name="image" accept="image/png, image/jpeg"> + </label><br> <div class="flex flex-col flex-wrap mb-4 space-y-4 md:flex-row md:items-end md:space-x-4"> <div> diff --git a/resources/views/admin/pages/index.blade.php b/resources/views/admin/pages/index.blade.php index aea947b..11abe0c 100644 --- a/resources/views/admin/pages/index.blade.php +++ b/resources/views/admin/pages/index.blade.php @@ -64,7 +64,7 @@ {{$page->name}} </td> <td class="px-4 py-3"> - {{ action([\App\Http\Controllers\PagesController::class, 'pages'], ['slug' => $page->slug]) }} + <a target="blank" href="{{ route('page', ['pages' => $page]) }}">{{ route('page', ['pages' => $page]) }}</a> </td> <td class="px-4 py-3"> {{$page->created_at}} diff --git a/resources/views/admin/reclames/index.blade.php b/resources/views/admin/reclames/index.blade.php new file mode 100644 index 0000000..d794ceb --- /dev/null +++ b/resources/views/admin/reclames/index.blade.php @@ -0,0 +1,98 @@ +@extends('layout.admin', ['title' => 'Админка - Реклама сайта']) + +@section('script') + +@endsection + +@section('search') + <!--<div class="absolute inset-y-0 flex items-center pl-2"> + <svg + class="w-4 h-4" + aria-hidden="true" + fill="currentColor" + viewBox="0 0 20 20" + > + <path + fill-rule="evenodd" + d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" + clip-rule="evenodd" + ></path> + </svg> + </div> + <form action="" method="POST"> + <div style="float:left;"><input + class="w-full pl-8 pr-2 text-sm text-gray-700 placeholder-gray-600 bg-gray-100 border-0 rounded-md dark:placeholder-gray-500 dark:focus:shadow-outline-gray dark:focus:placeholder-gray-600 dark:bg-gray-700 dark:text-gray-200 focus:placeholder-gray-500 focus:bg-white focus:border-purple-300 focus:outline-none focus:shadow-outline-purple form-input" + style="width: 400px" + type="text" + placeholder="Искать..." + aria-label="Search" + /></div> + <div style="float: left"> + <button type="submit" class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">Искать</button> + </div> + </form>--> +@endsection + +@section('content') + + <a href="{{ route('admin.add-seo') }}" style="width: 160px" class="px-3 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"> + Добавить рекламу + </a> + <br> + <div class="w-full overflow-hidden rounded-lg shadow-xs" id="ajax_block"> + + <div class="w-full overflow-x-auto"> + <table class="w-full whitespace-no-wrap"> + <thead> + <tr + class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800" + > + <th class="px-4 py-3">№</th> + <th class="px-4 py-3">Заголовок</th> + <th class="px-4 py-3">Ссылка</th> + <th class="px-4 py-3">Позиция</th> + <th class="px-4 py-3">Скрыть</th> + <th class="px-4 py-3">Клики</th> + <th class="px-4 py-3">Редактировать</th> + </tr> + </thead> + <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> + @foreach($reclames as $reclame) + <tr class="text-gray-700 dark:text-gray-400"> + <td class="px-4 py-3"> + {{$reclame->id}} + </td> + <td class="px-4 py-3"> + {{$reclame->title}} + </td> + <td class="px-4 py-3"> + {{$reclame->link}} + </td> + <td class="px-4 py-3"> + {{$reclame->position}} + </td> + <td class="px-4 py-3"> + {{$reclame->is_hidden}} + </td> + <td class="px-4 py-3"> + {{$reclame->col_vo_click}} + </td> + <td class="px-4 py-3 text-sm_"> + <form action="{{ route('admin.delete-seo', ['page' => $reclame->id]) }}" method="POST"> + <a href="{{ route('admin.edit-seo', ['page' => $reclame->id]) }}">Изменить</a> | + @csrf + @method('DELETE') + <input class="btn btn-danger" type="submit" value="Удалить"/> + </form> + </td> + </tr> + @endforeach + </tbody> + </table> + </div> + + <div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"> + <?=$reclames->appends($_GET)->links('admin.pagginate'); ?> + </div> + </div> +@endsection diff --git a/resources/views/admin/seo/add.blade.php b/resources/views/admin/seo/add.blade.php new file mode 100644 index 0000000..e69de29 diff --git a/resources/views/admin/seo/edit.blade.php b/resources/views/admin/seo/edit.blade.php new file mode 100644 index 0000000..e69de29 diff --git a/resources/views/admin/seo/form.blade.php b/resources/views/admin/seo/form.blade.php new file mode 100644 index 0000000..e69de29 diff --git a/resources/views/admin/seo/index.blade.php b/resources/views/admin/seo/index.blade.php new file mode 100644 index 0000000..2b46343 --- /dev/null +++ b/resources/views/admin/seo/index.blade.php @@ -0,0 +1,90 @@ +@extends('layout.admin', ['title' => 'Админка - Страницы SEO сайта']) + +@section('script') + +@endsection + +@section('search') + <!--<div class="absolute inset-y-0 flex items-center pl-2"> + <svg + class="w-4 h-4" + aria-hidden="true" + fill="currentColor" + viewBox="0 0 20 20" + > + <path + fill-rule="evenodd" + d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" + clip-rule="evenodd" + ></path> + </svg> + </div> + <form action="" method="POST"> + <div style="float:left;"><input + class="w-full pl-8 pr-2 text-sm text-gray-700 placeholder-gray-600 bg-gray-100 border-0 rounded-md dark:placeholder-gray-500 dark:focus:shadow-outline-gray dark:focus:placeholder-gray-600 dark:bg-gray-700 dark:text-gray-200 focus:placeholder-gray-500 focus:bg-white focus:border-purple-300 focus:outline-none focus:shadow-outline-purple form-input" + style="width: 400px" + type="text" + placeholder="Искать..." + aria-label="Search" + /></div> + <div style="float: left"> + <button type="submit" class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">Искать</button> + </div> + </form>--> +@endsection + +@section('content') + + <a href="{{ route('admin.add-seo') }}" style="width: 200px" class="px-3 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"> + Добавить seo странице + </a> + <br> + <div class="w-full overflow-hidden rounded-lg shadow-xs" id="ajax_block"> + + <div class="w-full overflow-x-auto"> + <table class="w-full whitespace-no-wrap"> + <thead> + <tr + class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800" + > + <th class="px-4 py-3">№</th> + <th class="px-4 py-3">URL страницы</th> + <th class="px-4 py-3">title страницы</th> + <th class="px-4 py-3">Дата создания</th> + <th class="px-4 py-3">Редактировать</th> + </tr> + </thead> + <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> + @foreach($pages as $page) + <tr class="text-gray-700 dark:text-gray-400"> + <td class="px-4 py-3"> + {{$page->id}} + </td> + <td class="px-4 py-3"> + {{$page->url}} + </td> + <td class="px-4 py-3"> + {{$page->title}} + </td> + <td class="px-4 py-3"> + {{$page->created_at}} + </td> + <td class="px-4 py-3 text-sm_"> + <form action="{{ route('admin.delete-seo', ['page' => $page->id]) }}" method="POST"> + <a href="{{ route('admin.edit-seo', ['page' => $page->id]) }}">Изменить</a> | + @csrf + @method('DELETE') + <input class="btn btn-danger" type="submit" value="Удалить"/> + </form> + </td> + </tr> + @endforeach + </tbody> + </table> + </div> + + <div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"> + <?=$pages->appends($_GET)->links('admin.pagginate'); ?> + </div> + </div> +@endsection diff --git a/routes/web.php b/routes/web.php index c972ec5..7dd4198 100644 --- a/routes/web.php +++ b/routes/web.php @@ -9,6 +9,7 @@ use App\Http\Controllers\Admin\UsersController; use App\Http\Controllers\Admin\WorkersController; use App\Http\Controllers\Auth\LoginController; use App\Http\Controllers\Auth\RegisterController; +use App\Http\Controllers\CKEditorController; use App\Models\User; use App\Http\Controllers\MainController; use App\Http\Controllers\HomeController; @@ -17,6 +18,7 @@ use App\Http\Controllers\Admin\CompanyController; use App\Http\Controllers\Admin\Ad_EmployersController; use App\Http\Controllers\Admin\MsgAnswersController; use App\Http\Controllers\Admin\GroupsController; +use App\Http\Controllers\PagesController; /* @@ -180,6 +182,11 @@ Route::group([ // кабинет - редактор seo-сайта Route::get('editor-seo', [CompanyController::class, 'editor_seo'])->name('editor-seo'); + Route::get('editor-seo/add', [CompanyController::class, 'editor_seo_add'])->name('add-seo'); + Route::post('editor-seo/add', [CompanyController::class, 'editor_seo_store'])->name('add-seo-store'); + Route::get('editor-seo/edit/{page}', [CompanyController::class, 'editor_seo_edit'])->name('edit-seo'); + Route::put('editor-seo/edit/{page}', [CompanyController::class, 'editor_seo_update'])->name('update-seo'); + Route::delete('editor-seo/delete/{page}', [CompanyController::class, 'editor_seo_destroy'])->name('delete-seo'); // кабинет - редактор страниц @@ -225,3 +232,7 @@ Route::group([ Route::get('roles', [UsersController::class, 'roles'])->name('roles'); }); + +Route::post('ckeditor/upload', [CKEditorController::class, 'upload'])->name('ckeditor.image-upload'); + +Route::get('pages/{pages:slug}', [PagesController::class, 'pages'])->name('page');