added cities and states controller

pull/44/head
A1Gard 2 months ago
parent 2a00c64fea
commit 2325536a26

@ -0,0 +1,127 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Controllers\XController;
use App\Http\Requests\CitySaveRequest;
use App\Models\Access;
use App\Models\City;
use App\Models\State;
use Illuminate\Http\Request;
use App\Helper;
use function App\Helpers\hasCreateRoute;
class CityController extends XController
{
// protected $_MODEL_ = City::class;
// protected $SAVE_REQUEST = CitySaveRequest::class;
protected $cols = ['name','state_id'];
protected $extra_cols = ['id'];
protected $searchable = [];
protected $listView = 'admin.cities.city-list';
protected $formView = 'admin.cities.city-form';
protected $buttons = [
'edit' =>
['title' => "Edit", 'class' => 'btn-outline-primary', 'icon' => 'ri-edit-2-line'],
'show' =>
['title' => "Detail", 'class' => 'btn-outline-light', 'icon' => 'ri-eye-line'],
'destroy' =>
['title' => "Remove", 'class' => 'btn-outline-danger delete-confirm', 'icon' => 'ri-close-line'],
];
public function __construct()
{
parent::__construct(City::class, CitySaveRequest::class);
}
/**
* @param $city City
* @param $request CitySaveRequest
* @return City
*/
public function save($city, $request)
{
$city->name = $request->name;
$city->state_id = $request->state_id;
$city->lat = $request->lat;
$city->lng = $request->lng;
$city->save();
return $city;
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
$states = State::orderBy('name')->get(['id', 'name']);
return view($this->formView,compact('states'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(City $item)
{
//
$states = State::orderBy('name')->get(['id', 'name']);
return view($this->formView, compact('item','states'));
}
public function bulk(Request $request)
{
// dd($request->all());
$data = explode('.', $request->input('action'));
$action = $data[0];
$ids = $request->input('id');
switch ($action) {
case 'delete':
$msg = __(':COUNT items deleted successfully', ['COUNT' => count($ids)]);
$this->_MODEL_::destroy($ids);
break;
/**restore*/
case 'restore':
$msg = __(':COUNT items restored successfully', ['COUNT' => count($ids)]);
foreach ($ids as $id) {
$this->_MODEL_::withTrashed()->find($id)->restore();
}
break;
/*restore**/
default:
$msg = __('Unknown bulk action : :ACTION', ["ACTION" => $action]);
}
return $this->do_bulk($msg, $action, $ids);
}
public function destroy(City $item)
{
return parent::delete($item);
}
public function update(Request $request, City $item)
{
return $this->bringUp($request, $item);
}
/**restore*/
public function restore($item)
{
return parent::restoreing(City::withTrashed()->where('id', $item)->first());
}
/*restore**/
}

@ -0,0 +1,125 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Controllers\XController;
use App\Http\Requests\StateSaveRequest;
use App\Models\Access;
use App\Models\State;
use Illuminate\Http\Request;
use App\Helper;
use function App\Helpers\hasCreateRoute;
class StateController extends XController
{
// protected $_MODEL_ = State::class;
// protected $SAVE_REQUEST = StateSaveRequest::class;
protected $cols = ['name','country'];
protected $extra_cols = ['id'];
protected $searchable = [];
protected $listView = 'admin.states.state-list';
protected $formView = 'admin.states.state-form';
protected $buttons = [
'edit' =>
['title' => "Edit", 'class' => 'btn-outline-primary', 'icon' => 'ri-edit-2-line'],
'show' =>
['title' => "Detail", 'class' => 'btn-outline-light', 'icon' => 'ri-eye-line'],
'destroy' =>
['title' => "Remove", 'class' => 'btn-outline-danger delete-confirm', 'icon' => 'ri-close-line'],
];
public function __construct()
{
parent::__construct(State::class, StateSaveRequest::class);
}
/**
* @param $state State
* @param $request StateSaveRequest
* @return State
*/
public function save($state, $request)
{
$state->name = $request->name;
$state->country = $request->country;
$state->lat = $request->lat;
$state->lng = $request->lng;
$state->save();
return $state;
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
return view($this->formView);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(State $item)
{
//
return view($this->formView, compact('item'));
}
public function bulk(Request $request)
{
// dd($request->all());
$data = explode('.', $request->input('action'));
$action = $data[0];
$ids = $request->input('id');
switch ($action) {
case 'delete':
$msg = __(':COUNT items deleted successfully', ['COUNT' => count($ids)]);
$this->_MODEL_::destroy($ids);
break;
/**restore*/
case 'restore':
$msg = __(':COUNT items restored successfully', ['COUNT' => count($ids)]);
foreach ($ids as $id) {
$this->_MODEL_::withTrashed()->find($id)->restore();
}
break;
/*restore**/
default:
$msg = __('Unknown bulk action : :ACTION', ["ACTION" => $action]);
}
return $this->do_bulk($msg, $action, $ids);
}
public function destroy(State $item)
{
return parent::delete($item);
}
public function update(Request $request, State $item)
{
return $this->bringUp($request, $item);
}
/**restore*/
public function restore($item)
{
return parent::restoreing(State::withTrashed()->where('id', $item)->first());
}
/*restore**/
}

@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CitySaveRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
//
'name' => ['required','string','min:2'] ,
'state_id' => ['required','exists:states,id'] ,
'lat' => ['required','numeric','between:-90,90'],
'lng' => ['required','numeric','between:-180,180'],
];
}
}

@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StateSaveRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
//
'name' => ['required','string','min:2'] ,
'country' => ['required','string','min:2'],
'lat' => ['required','numeric','between:-90,90'],
'lng' => ['required','numeric','between:-180,180'],
];
}
}

@ -12,4 +12,8 @@ class City extends Model
use HasTranslations,SoftDeletes;
public $translatable = ['name'];
public function state(){
return $this->belongsTo(State::class);
}
}

@ -93,6 +93,8 @@ app.component('gfxer', Gfxer);
import AreaDesginer from "./components/AreaDesginer.vue";
app.component('area-designer', AreaDesginer);
import Latlng from "./components/latlng.vue";
app.component('lat-lng', Latlng);
/**
* The following block of code may be used to automatically register your

@ -0,0 +1,113 @@
<template>
<div id="latlng">
<div ref="mapContainer" :style="'height: 300px;'+mapStyle"></div>
</div>
</template>
<script>
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
export default {
name: "latlng",
components: {},
data: () => {
return {
map: null,
marker: null,
zoom: 10,
address: '',
zip: '',
lat: null,
lng: null,
}
},
props: {
darkMode: {
type: Boolean,
default: false,
},
ilat: { // init lat
type: Number,
default: 35.83266000,
},
ilng: { // init lng
type: Number,
default: 50.99155000,
},
izoom:{
type: Number,
default: 10,
},
},
mounted() {
this.lat = this.ilat;
this.lng = this.ilng;
this.zoom = this.izoom;
this.initMap();
},
computed: {
mapStyle() {
if (this.darkMode) {
return 'filter: invert(100%) hue-rotate(120deg) brightness(95%) contrast(90%);';
}
return '';
}
},
methods: {
initMap() {
this.map = L.map(this.$refs.mapContainer).setView([this.lat, this.lng], this.zoom);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; openstreetmap',
attributionControl: false,
}).addTo(this.map);
this.map.on('click', this.onMapClick);
this.map.attributionControl.setPrefix('xShop');
},
onMapClick(e) {
if (this.marker) {
this.map.removeLayer(this.marker);
}
this.marker = L.marker(e.latlng).addTo(this.map);
// You can emit the selected location or perform any other desired action here
// console.log('Selected location:', e.latlng);
this.lat = e.latlng.lat;
this.lng = e.latlng.lng;
try {
document.querySelector('#lat').value = this.lat;
document.querySelector('#lng').value = this.lng;
} catch(e) {
console.log(e.message);
}
},
// changeMapCenter(lat, lng) {
// try {
//
// this.map.setView([lat, lng], this.zoom);
// } catch (e) {
// // console.log(e.message);
// setTimeout(() => {
// console.log('repeat');
// this.changeMapCenter(lat, lng);
// }, 10);
// }
//
// // Change the map center to [40.7128, -74.0059] (New York City) with zoom level 12
//
// },
}
}
</script>
<style scoped>
#latlng {
}
</style>

@ -17,13 +17,6 @@ window.findUrl = function (name, item = null) {
document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('click', function (e) {
if (e.target.classList.contains('delete-confirm')) {
if (!confirm('Are you sure you want to delete this item?')) { // WIP Need to translate
e.preventDefault();
}
}
});
document.querySelectorAll('.delete-confirm')?.forEach(function (el) {
el.addEventListener('click', function (e) {

@ -0,0 +1,106 @@
@extends('admin.templates.panel-form-template')
@section('title')
@if(isset($item))
{{__("Edit city")}} [{{$item->name}}]
@else
{{__("Add new city")}}
@endif -
@endsection
@section('form')
<div class="row">
<div class="col-lg-3">
@include('components.err')
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-message-3-line"></i>
{{__("Tips")}}
</h3>
<ul>
<li>
{{__("Recommends")}}
</li>
</ul>
</div>
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-map-2-line"></i>
{{__("Change latitude and longitude")}}
</h3>
<div class="p3">
<lat-lng dark-mode="true"
@if(isset($item))
:ilat="{{$item->lat}}"
:ilng="{{$item->lng}}"
@endif
:izoom="12"
></lat-lng>
</div>
</div>
</div>
<div class="col-lg-9 ps-xl-1 ps-xxl-1">
<div class="general-form ">
<h1>
@if(isset($item))
{{__("Edit city")}} [{{$item->name}}]
@else
{{__("Add new city")}}
@endif
</h1>
<div class="row">
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="name" >
{{__('Name')}}
</label>
<input name="name" type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="{{__('Name')}}" value="{{old('name',$item->name??null)}}" />
</div>
</div>
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="state_id" >
{{__('State')}}
</label>
<searchable-select
@error('state_id') :err="true" @enderror
:items='@json($states)'
title-field="name"
value-field="id"
xlang="{{config('app.locale')}}"
xid="state_id"
xname="state_id"
@error('state_id') :err="true" @enderror
xvalue='{{old('state_id',$item->state_id??null)}}'
:close-on-Select="true"></searchable-select>
</div>
</div>
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="lat" >
{{__('Latitude')}}
</label>
<input readonly name="lat" type="text" class="form-control @error('lat') is-invalid @enderror" id="lat" placeholder="{{__('Latitude')}}" value="{{old('lat',$item->lat??null)}}" />
</div>
</div>
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="lng" >
{{__('Longitude')}}
</label>
<input readonly name="lng" type="text" class="form-control @error('lng') is-invalid @enderror" id="lng" placeholder="{{__('Longitude')}}" value="{{old('lng',$item->lng??null)}}" />
</div>
</div>
<div class="col-12">
<label> &nbsp; </label>
<input name="" id="" type="submit" class="btn btn-primary mt-2" value="{{__('Save')}}" />
</div>
</div>
</div>
</div>
</div>
@endsection

@ -0,0 +1,15 @@
@extends('admin.templates.panel-list-template')
@section('list-title')
<i class="ri-user-3-line"></i>
{{__("Cities list")}}
@endsection
@section('title')
{{__("Cities list")}} -
@endsection
@section('filter')
{{-- Other filters --}}
@endsection
@section('bulk')
{{-- <option value="-"> - </option> --}}
@endsection

@ -0,0 +1,93 @@
@extends('admin.templates.panel-form-template')
@section('title')
@if(isset($item))
{{__("Edit state")}} [{{$item->name}}]
@else
{{__("Add new state")}}
@endif -
@endsection
@section('form')
<div class="row">
<div class="col-lg-3">
@include('components.err')
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-message-3-line"></i>
{{__("Tips")}}
</h3>
<ul>
<li>
{{__("Recommends")}}
</li>
</ul>
</div>
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-map-2-line"></i>
{{__("Change latitude and longitude")}}
</h3>
<div class="p3">
<lat-lng dark-mode="true"
@if(isset($item))
:ilat="{{$item->lat}}"
:ilng="{{$item->lng}}"
@endif
></lat-lng>
</div>
</div>
</div>
<div class="col-lg-9 ps-xl-1 ps-xxl-1">
<div class="general-form ">
<h1>
@if(isset($item))
{{__("Edit state")}} [{{$item->name}}]
@else
{{__("Add new state")}}
@endif
</h1>
<div class="row">
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="name" >
{{__('Name')}}
</label>
<input name="name" type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="{{__('Name')}}" value="{{old('name',$item->name??null)}}" />
</div>
</div>
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="country" >
{{__('Country')}}
</label>
<input name="country" type="text" class="form-control @error('country') is-invalid @enderror" id="country" placeholder="{{__('Country')}}" value="{{old('country',$item->country??null)}}" />
</div>
</div>
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="lat" >
{{__('Latitude')}}
</label>
<input readonly name="lat" type="text" class="form-control @error('lat') is-invalid @enderror" id="lat" placeholder="{{__('Latitude')}}" value="{{old('lat',$item->lat??null)}}" />
</div>
</div>
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="lng" >
{{__('Longitude')}}
</label>
<input readonly name="lng" type="text" class="form-control @error('lng') is-invalid @enderror" id="lng" placeholder="{{__('Longitude')}}" value="{{old('lng',$item->lng??null)}}" />
</div>
</div>
<div class="col-12">
<label> &nbsp; </label>
<input name="" id="" type="submit" class="btn btn-primary mt-2" value="{{__('Save')}}" />
</div>
</div>
</div>
</div>
@endsection

@ -0,0 +1,15 @@
@extends('admin.templates.panel-list-template')
@section('list-title')
<i class="ri-user-3-line"></i>
{{__("States list")}}
@endsection
@section('title')
{{__("States list")}} -
@endsection
@section('filter')
{{-- Other filters --}}
@endsection
@section('bulk')
{{-- <option value="-"> - </option> --}}
@endsection

@ -195,6 +195,11 @@
{{ $item->category?->name??'-' }}
</a>
@break
@case('state_id')
<a href="{{route('admin.category.edit',$item->state?->id)}}">
{{ $item->state?->name??'-' }}
</a>
@break
@case('product_id')
<a href="{{route('admin.product.edit',$item->product?->slug)}}">
{{ $item->product?->name??'-' }}

@ -184,10 +184,28 @@
<ul id="manage">
<li>
<a href="{{route('admin.user.index')}}">
<i class="ri-folder-user-fill"></i>
<i class="ri-user-line"></i>
{{__("Users")}}
</a>
</li>
<li>
<a href="{{route('admin.state.index')}}">
<i class="ri-map-line"></i>
{{__("States")}}
</a>
</li>
<li>
<a href="{{route('admin.city.index')}}">
<i class="ri-map-2-line"></i>
{{__("City")}}
</a>
</li>
<li>
<a href="">
<i class="ri-bar-chart-2-line"></i>
{{__("Reports")}}
</a>
</li>
<li>
<a href="{{route('admin.adminlog.index')}}">
<i class="ri-list-check-3"></i>
@ -206,12 +224,6 @@
{{__("Languages")}}
</a>
</li>
<li>
<a href="">
<i class="ri-bar-chart-2-line"></i>
{{__("Reports")}}
</a>
</li>
</ul>
</li>
<li data-bs-toggle="tooltip" data-bs-placement="auto" data-bs-custom-class="custom-tooltip"

@ -199,6 +199,32 @@ Route::prefix(config('app.panel.prefix'))->name('admin.')->group(
Route::post('bulk', [\App\Http\Controllers\Admin\CustomerController::class, "bulk"])->name('bulk');
Route::get('trashed', [\App\Http\Controllers\Admin\CustomerController::class, "trashed"])->name('trashed');
});
Route::prefix('states')->name('state.')->group(
function () {
Route::get('', [\App\Http\Controllers\Admin\StateController::class, 'index'])->name('index');
Route::get('create', [\App\Http\Controllers\Admin\StateController::class, 'create'])->name('create');
Route::post('store', [\App\Http\Controllers\Admin\StateController::class, 'store'])->name('store');
Route::get('show/{item}', [\App\Http\Controllers\Admin\StateController::class, 'show'])->name('show');
Route::get('edit/{item}', [\App\Http\Controllers\Admin\StateController::class, 'edit'])->name('edit');
Route::post('update/{item}', [\App\Http\Controllers\Admin\StateController::class, 'update'])->name('update');
Route::get('delete/{item}', [\App\Http\Controllers\Admin\StateController::class, 'destroy'])->name('destroy');
Route::get('restore/{item}', [\App\Http\Controllers\Admin\StateController::class, 'restore'])->name('restore');
Route::post('bulk', [\App\Http\Controllers\Admin\StateController::class, "bulk"])->name('bulk');
Route::get('trashed', [\App\Http\Controllers\Admin\StateController::class, "trashed"])->name('trashed');
});
Route::prefix('cities')->name('city.')->group(
function () {
Route::get('', [\App\Http\Controllers\Admin\CityController::class, 'index'])->name('index');
Route::get('create', [\App\Http\Controllers\Admin\CityController::class, 'create'])->name('create');
Route::post('store', [\App\Http\Controllers\Admin\CityController::class, 'store'])->name('store');
Route::get('show/{item}', [\App\Http\Controllers\Admin\CityController::class, 'show'])->name('show');
Route::get('edit/{item}', [\App\Http\Controllers\Admin\CityController::class, 'edit'])->name('edit');
Route::post('update/{item}', [\App\Http\Controllers\Admin\CityController::class, 'update'])->name('update');
Route::get('delete/{item}', [\App\Http\Controllers\Admin\CityController::class, 'destroy'])->name('destroy');
Route::get('restore/{item}', [\App\Http\Controllers\Admin\CityController::class, 'restore'])->name('restore');
Route::post('bulk', [\App\Http\Controllers\Admin\CityController::class, "bulk"])->name('bulk');
Route::get('trashed', [\App\Http\Controllers\Admin\CityController::class, "trashed"])->name('trashed');
});
Route::prefix('galleries')->name('gallery.')->group(
function () {
Route::get('', [\App\Http\Controllers\Admin\GalleryController::class, 'index'])->name('index');

Loading…
Cancel
Save