added customer controller

added state and city
installed api route
added address input
pull/44/head
A1Gard 6 months ago
parent a20dc80748
commit 62debcbe6d

@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Route;
* @param $lang code like fa
* @return string
*/
function getEmojiLanguagebyCode($lang) : string
function getEmojiLanguagebyCode($lang): string
{
$languages = [
"af" => "🇿🇦", // Afrikaans
@ -93,12 +93,12 @@ function getEmojiLanguagebyCode($lang) : string
* @return bool
*/
function hasRoute($name) : bool
function hasRoute($name): bool
{
// create route
$routes = explode('.',request()->route()->getName());
$routes[count($routes) - 1 ] = $name;
$cRuote = implode('.',$routes);
$routes = explode('.', request()->route()->getName());
$routes[count($routes) - 1] = $name;
$cRuote = implode('.', $routes);
if (\Illuminate\Support\Facades\Route::has($cRuote)) {
return true;
@ -113,12 +113,12 @@ function hasRoute($name) : bool
* @param $args array
* @return string|null
*/
function getRoute($name, $args = []) : string | null
function getRoute($name, $args = []): string|null
{
// create route
$routes = explode('.',request()->route()->getName());
$routes[count($routes) - 1 ] = $name;
$cRuote = implode('.',$routes);
$routes = explode('.', request()->route()->getName());
$routes[count($routes) - 1] = $name;
$cRuote = implode('.', $routes);
if (\Illuminate\Support\Facades\Route::has($cRuote)) {
return \route($cRuote, $args);
@ -133,7 +133,7 @@ function getRoute($name, $args = []) : string | null
* @param $col string
* @return string
*/
function sortSuffix($col) : string
function sortSuffix($col): string
{
if (request()->sort == $col) {
if (request('sortType', 'asc') == 'desc') {
@ -153,7 +153,7 @@ function sortSuffix($col) : string
* @param $translate
* @return false|string
*/
function arrayNormolizeVueCompatible($array, $translate = false): false | string
function arrayNormolizeVueCompatible($array, $translate = false): false|string
{
$result = [];
foreach ($array as $index => $item) {
@ -168,7 +168,8 @@ function arrayNormolizeVueCompatible($array, $translate = false): false | string
* @param $string
* @return bool
*/
function isJson($string) : bool {
function isJson($string): bool
{
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
@ -200,7 +201,7 @@ function logAdminBatch($method, $cls, $ids): void
* @param $id
* @return void
*/
function logAdmin($method, $cls, $id) :void
function logAdmin($method, $cls, $id): void
{
$act = explode('\\', $method);
auth()->user()->logs()->create([
@ -216,9 +217,10 @@ function logAdmin($method, $cls, $id) :void
* @param $except
* @return string
*/
function queryBuilder($except = null){
function queryBuilder($except = null)
{
$queries = request()->toArray();
if ($except != null){
if ($except != null) {
unset($queries[$except]);
unset($queries['sortType']);
}
@ -234,7 +236,7 @@ function queryBuilder($except = null){
function sluger($name, $replace_char = '-')
{
// special chars
$name = str_replace(['&', '+' , '@', '*'], ['and', 'plus', 'at', 'star'], $name);
$name = str_replace(['&', '+', '@', '*'], ['and', 'plus', 'at', 'star'], $name);
// replace non letter or digits by -
$name = preg_replace('~[^\pL\d\.]+~u', $replace_char, $name);
@ -367,9 +369,10 @@ function showCatNestedControl($cats, $checked = [], $parent = null)
* @param $modelable_id
* @return string
*/
function getModelName($modelable_type,$modelable_id){
$r = explode('\\',$modelable_type);
return $r[count($r)-1].':'.$modelable_id;
function getModelName($modelable_type, $modelable_id)
{
$r = explode('\\', $modelable_type);
return $r[count($r) - 1] . ':' . $modelable_id;
}
/**
@ -378,22 +381,36 @@ function getModelName($modelable_type,$modelable_id){
* @param $modelable_id
* @return string
*/
function getModelLink($modelable_type,$modelable_id){
$r = explode('\\',$modelable_type);
$model = strtolower($r[count($r)-1]);
$name = 'admin.'.$model.'.show';
if (Route::has($name)){
return \route($name,$modelable_id);
}else{
function getModelLink($modelable_type, $modelable_id)
{
$r = explode('\\', $modelable_type);
$model = strtolower($r[count($r) - 1]);
$name = 'admin.' . $model . '.show';
if (Route::has($name)) {
return \route($name, $modelable_id);
} else {
return '';
}
}
function getAction($act){
$r = explode('::',$act);
return ucfirst($r[count($r)-1]);
function getAction($act)
{
$r = explode('::', $act);
return ucfirst($r[count($r) - 1]);
}
function getAdminRoutes()
{
$routes = [];
foreach (Illuminate\Support\Facades\Route::getRoutes() as $r) {
if (strpos($r->getName(), 'admin') !== false) {
$routes[] = [
'name' => $r->getName(),
'url' => $r->uri(),
];
}
}
return $routes;
}

@ -0,0 +1,78 @@
<?php
namespace App\Helpers;
class PersianFaker
{
private static $mobile_prefix = ['0912', '0919', '0935', '0936', '0937', '0933', '0938', '0915'];
private static $card_prefix = ['6037', '6104', '6391', '6280', '6273', '6287', '6280', '5022'];
private static $colors = [
'red' => ['name' => 'قرمز', 'code' => '#ff0000'],
'blue' => ['name' => 'آبی', 'code' => '#0000ff'],
'green' => ['name' => 'سبز', 'code' => '#008000'],
'yellow' => ['name' => 'زرد', 'code' => '#ffff00'],
'purple' => ['name' => 'بنفش', 'code' => '#800080'],
'orange' => ['name' => 'نارنجی', 'code' => '#ffa500'],
'pink' => ['name' => 'صورتی', 'code' => '#ffc0cb'],
'white' => ['name' => 'سفید', 'code' => '#ffffff'],
'black' => ['name' => 'سیاه', 'code' => '#000000'],
'grey' => ['name' => 'خاکستری', 'code' => '#808080'],
'brown' => ['name' => 'قهوه‌ای', 'code' => '#a52a2a'],
'silver' => ['name' => 'نقره‌ای', 'code' => '#c0c0c0'],
'gold' => ['name' => 'طلایی', 'code' => '#ffd700'],
'turquoise' => ['name' => 'فیروزه ای', 'code' => '#40e0d0'],
'magenta' => ['name' => 'بنفش روشن', 'code' => '#ff00ff'],
'cyan' => ['name' => 'فیروزی', 'code' => '#00ffff'],
'maroon' => ['name' => 'آبی کمرنگ', 'code' => '#800000'],
'navy' => ['name' => 'نیرویی', 'code' => '#000080'],
'teal' => ['name' => 'نیلی', 'code' => '#008080'],
'olive' => ['name' => 'زیتونی', 'code' => '#808000'],
];
static public function mobile()
{
return self::$mobile_prefix[rand(0, count(self::$mobile_prefix) - 1)] . rand(1000000, 9999999);
}
static public function shetabCard()
{
return self::$card_prefix[rand(0, count(self::$card_prefix) - 1)] . '-'
. rand(1000, 9999) . '-' . rand(1000, 9999) . '-' . rand(1000, 9999);
}
static function validCodeMeli()
{
do {
$randomNumber = str_pad(mt_rand(1, 99999999), 8, '0', STR_PAD_LEFT);
$code = '0000' . $randomNumber;
$code = substr($code, strlen($code) - 10, 10);
if (intval(substr($code, 3, 6)) == 0) {
continue;
}
$checksum = intval(substr($code, 9, 1));
$s = 0;
for ($i = 0; $i < 9; $i++) {
$s += intval(substr($code, $i, 1)) * (10 - $i);
}
$s = $s % 11;
if (($s < 2 && $checksum == $s) || ($s >= 2 && $checksum == (11 - $s))) {
return $code;
}
} while (true);
}
static public function color(){
$colors = self::$colors;
shuffle($colors);
return $colors[0];
}
}

@ -0,0 +1,118 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Address;
use App\Models\Customer;
use Illuminate\Http\Request;
class AddressController extends Controller
{
public function save(Address $address, Request $request)
{
$address->address = $request->input('address');
$address->lat = $request->input('lat');
$address->lng = $request->input('lng');
$address->state_id = $request->input('state_id')??null;
$address->city_id = $request->input('city_id')??null;
$address->zip = $request->input('zip');
$address->save();
return $address;
}
/**
* Display a listing of the resource.
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request, Customer $item)
{
//
$request->validate([
'address' => ['required', 'string', 'min:10'],
'zip' => ['required', 'string', 'min:5'],
'state_id' => ['required', 'exists:states,id'],
'city_id' => ['required', 'exists:cities,id'],
'lat' => ['nullable'],
'lng' => ['nullable'],
]);
$address = new Address();
$address->customer_id = $item->id;
$address = $this->save($address, $request);
logAdmin(__METHOD__,Address::class,$address->id);
return ['OK' => true,'message' => __("Address added to :CUSTOMER",['CUSTOMER'=>$item->name]), 'list'=> $item->addresses];
}
/**
* Display the specified resource.
*/
public function show(Address $address)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Address $address)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Address $item)
{
//
$request->validate([
'address' => ['required', 'string', 'min:10'],
'zip' => ['required', 'string', 'min:5'],
'state_id' => ['required', 'exists:states,id'],
'city_id' => ['required', 'exists:cities,id'],
'lat' => ['nullable'],
'lng' => ['nullable'],
]);
$this->save($item, $request);
logAdmin(__METHOD__,Address::class,$item->id);
return ['OK' => true, "message" => __("address updated")];
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Address $item)
{
//
$add = $item->address ;
logAdmin(__METHOD__,Address::class,$item->id);
$item->delete();
return ['OK' => true, "message" => __(":ADDRESS removed",['ADDRESS' => $add])];
}
public function customer(Customer $item)
{
return $item->addresses;
}
}

@ -99,7 +99,13 @@ class CategoryController extends XController
$msg = __(':COUNT items deleted successfully', ['COUNT' => count($ids)]);
$this->_MODEL_::destroy($ids);
break;
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]);
}
@ -118,5 +124,11 @@ class CategoryController extends XController
return $this->bringUp($request, $item);
}
/**restore*/
public function restore($item)
{
return parent::restoreing(Category::withTrashed()->where('id', $item)->first());
}
/*restore**/
}

@ -0,0 +1,139 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Controllers\XController;
use App\Http\Requests\CustomerSaveRequest;
use App\Models\Access;
use App\Models\Customer;
use Illuminate\Http\Request;
use App\Helper;
use function App\Helpers\hasCreateRoute;
class CustomerController extends XController
{
// protected $_MODEL_ = Customer::class;
// protected $SAVE_REQUEST = CustomerSaveRequest::class;
protected $cols = ['name','mobile','email'];
protected $extra_cols = ['id','deleted_at'];
protected $searchable = ['name','mobile','email'];
protected $listView = 'admin.customers.customer-list';
protected $formView = 'admin.customers.customer-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(Customer::class, CustomerSaveRequest::class);
}
/**
* @param $customer Customer
* @param $request CustomerSaveRequest
* @return Customer
*/
public function save($customer, $request)
{
$customer->name = $request->input('name');
$customer->address = $request->input('address');
$customer->state = $request->input('state');
$customer->credit = $request->input('credit')??0 ;
$customer->city = $request->input('city');
$customer->postal_code = $request->input('postal_code');
if ($request->has('email')) {
$customer->email = $request->input('email');
}
$customer->mobile = $request->input('mobile');
$customer->description = $request->input('description');
if (trim($request->input('password')) != '') {
$customer->password = bcrypt($request->input('password'));
}
$customer->colleague = $request->has('colleague');
$customer->save();
return $customer;
}
/**
* 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(Customer $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(Customer $item)
{
return parent::delete($item);
}
public function update(Request $request, Customer $item)
{
return $this->bringUp($request, $item);
}
/**restore*/
public function restore($item)
{
return parent::restoreing(Customer::withTrashed()->where('id', $item)->first());
}
/*restore**/
}

@ -0,0 +1,70 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\CityCollection;
use App\Http\Resources\StateCollection;
use App\Models\State;
use Illuminate\Http\Request;
class StateController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
return StateCollection::collection(State::all());
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(State $state)
{
//
return CityCollection::collection($state->cities);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(State $state)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, State $state)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(State $state)
{
//
}
}

@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CustomerSaveRequest 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', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:customers,email'],
'password' => ['nullable', 'string', 'min:6', 'confirmed'],
'mobile'=> ['required', 'string', 'min:10'],
];
}
}

@ -0,0 +1,25 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\Json\ResourceCollection;
class CityCollection extends JsonResource
{
/**
* Transform the resource collection into an array.
*
* @return array<int|string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'lat' => $this->lat,
'lng' => $this->lng
];
}
}

@ -0,0 +1,26 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\Json\ResourceCollection;
class StateCollection extends JsonResource
{
/**
* Transform the resource collection into an array.
*
* @return array<int|string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'country' => $this->country,
'lat' => $this->lat,
'lng' => $this->lng
];
}
}

@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Translatable\HasTranslations;
class City extends Model
{
use HasTranslations,SoftDeletes;
public $translatable = ['name'];
}

@ -4,8 +4,44 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Customer extends Model
class Customer extends Authenticatable
{
use HasFactory;
use HasFactory, SoftDeletes;
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
'dob' => 'date'
];
public function invoices(){
return $this->hasMany(Invoice::class);
}
public function tickets(){
return $this->hasMany(Ticket::class);
}
public function main_tickets(){
return $this->hasMany(Ticket::class)->whereNull('parent_id');
}
public function products(){
return $this->belongsToMany(Product::class,'customer_product');
}
public function credits(){
return $this->hasMany(Credit::class);
}
public function addresses(){
return $this->hasMany(Address::class);
}
}

@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Translatable\HasTranslations;
class State extends Model
{
use HasFactory,HasTranslations,SoftDeletes;
public $translatable = ['name', 'country'];
public function cities(){
return $this->hasMany(City::class);
}
}

@ -7,6 +7,7 @@ use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)

@ -14,6 +14,7 @@
"dpsoft/saderat": "^4.0",
"dpsoft/zibal": "^2.0",
"laravel/framework": "^11.0",
"laravel/sanctum": "^4.0",
"laravel/tinker": "^2.9",
"laravel/ui": "^4.5",
"pishran/zarinpal": "^4.3",

66
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": "dbfddb0272c6537f8f25994eb973c21e",
"content-hash": "c313d4b398df8da8dc636019a4659513",
"packages": [
{
"name": "brick/math",
@ -1766,6 +1766,70 @@
},
"time": "2024-05-27T13:53:20+00:00"
},
{
"name": "laravel/sanctum",
"version": "v4.0.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/sanctum.git",
"reference": "9cfc0ce80cabad5334efff73ec856339e8ec1ac1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/9cfc0ce80cabad5334efff73ec856339e8ec1ac1",
"reference": "9cfc0ce80cabad5334efff73ec856339e8ec1ac1",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/console": "^11.0",
"illuminate/contracts": "^11.0",
"illuminate/database": "^11.0",
"illuminate/support": "^11.0",
"php": "^8.2",
"symfony/console": "^7.0"
},
"require-dev": {
"mockery/mockery": "^1.6",
"orchestra/testbench": "^9.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.5"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Laravel\\Sanctum\\SanctumServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Laravel\\Sanctum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.",
"keywords": [
"auth",
"laravel",
"sanctum"
],
"support": {
"issues": "https://github.com/laravel/sanctum/issues",
"source": "https://github.com/laravel/sanctum"
},
"time": "2024-04-10T19:39:58+00:00"
},
{
"name": "laravel/serializable-closure",
"version": "v1.3.3",

@ -0,0 +1,83 @@
<?php
use Laravel\Sanctum\Sanctum;
return [
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
/*
|--------------------------------------------------------------------------
| Sanctum Guards
|--------------------------------------------------------------------------
|
| This array contains the authentication guards that will be checked when
| Sanctum is trying to authenticate a request. If none of these guards
| are able to authenticate the request, Sanctum will use the bearer
| token that's present on an incoming request for authentication.
|
*/
'guard' => ['web'],
/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. This will override any values set in the token's
| "expires_at" attribute, but first-party sessions are not affected.
|
*/
'expiration' => null,
/*
|--------------------------------------------------------------------------
| Token Prefix
|--------------------------------------------------------------------------
|
| Sanctum can prefix new tokens in order to take advantage of numerous
| security scanning initiatives maintained by open source platforms
| that notify developers if they commit tokens into repositories.
|
| See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
|
*/
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
/*
|--------------------------------------------------------------------------
| Sanctum Middleware
|--------------------------------------------------------------------------
|
| When authenticating your first-party SPA with Sanctum you may need to
| customize some of the middleware Sanctum uses while processing the
| request. You may change the middleware listed below as required.
|
*/
'middleware' => [
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
],
];

@ -2,6 +2,7 @@
namespace Database\Factories;
use App\Helpers\PersianFaker;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
@ -17,7 +18,12 @@ class CustomerFactory extends Factory
public function definition(): array
{
return [
//
'name' => $this->faker->name,
'mobile' => PersianFaker::mobile(),
'email' => $this->faker->unique()->email,
'password' => bcrypt('password'),
'credit' => 0,
'description' => __('Credit card:').PHP_EOL.PersianFaker::shetabCard(),
];
}
}

@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\State>
*/
class StateFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
//
];
}
}

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('states', function (Blueprint $table) {
$table->id();
$table->text('name');
$table->double('lat');
$table->double('lng');
$table->text('country');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('states');
}
};

@ -18,18 +18,16 @@ return new class extends Migration
$table->timestamp('email_verified_at')->nullable()->default(null);
$table->string('password')->nullable()->default(null);
$table->unsignedInteger('state')->nullable()->default(null);
$table->unsignedInteger('city')->nullable()->default(null);
$table->string('mobile',15)->unique()->nullable()->default(null);
$table->string('address',2048)->nullable()->default(null);
$table->string('postal_code',15)->nullable()->default(null);
$table->date('dob')->nullable()->default(null);
$table->string('sms',10)->nullable()->default(null);
$table->string('code',10)->nullable()->default(null);
$table->boolean('colleague')->default(false);
$table->text('description')->default(null)->nullable();
$table->unsignedBigInteger('credit')->default(0);
$table->bigInteger('credit')->default(0);
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
}

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('cities', function (Blueprint $table) {
$table->id();
$table->text('name');
$table->double('lat')->nullable();
$table->double('lng')->nullable();
$table->unsignedBigInteger('state_id');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('cities');
}
};

@ -17,13 +17,18 @@ return new class extends Migration
$table->unsignedBigInteger('customer_id');
$table->double('lat')->nullable();
$table->double('lng')->nullable();
$table->unsignedInteger('state')->nullable()->default(null);
$table->unsignedInteger('city')->nullable()->default(null);
$table->json('data');
$table->unsignedBigInteger('state_id')->nullable()->default(null);
$table->unsignedBigInteger('city_id')->nullable()->default(null);
$table->json('data')->nullable();
$table->string('zip')->nullable()->comment('postal code');
$table->timestamps();
$table->softDeletes();
$table->foreign('customer_id')->references('id')
->on('customers')->onDelete('cascade');
$table->foreign('state_id')->references('id')
->on('states')->onDelete('cascade');
$table->foreign('city_id')->references('id')
->on('cities')->onDelete('cascade');
});
}

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('personal_access_tokens');
}
};

@ -2,6 +2,7 @@
namespace Database\Seeders;
use App\Models\Customer;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
@ -13,5 +14,6 @@ class CustomerSeeder extends Seeder
public function run(): void
{
//
Customer::factory(35)->create();
}
}

@ -2,7 +2,9 @@
namespace Database\Seeders;
use App\Models\Customer;
use App\Models\Post;
use App\Models\State;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Storage;
@ -24,10 +26,11 @@ class DatabaseSeeder extends Seeder
');
$this->call([
UserSeeder::class,
GroupSeeder::class,
PostSeeder::class,
StateSeeder::class,
CustomerSeeder::class,
]
);
}

File diff suppressed because one or more lines are too long

872
package-lock.json generated

@ -0,0 +1,872 @@
{
"name": "xshop2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"remixicon": "^4.2.0",
"three": "0.150.0",
"vazirmatn": "^33.0.3"
},
"devDependencies": {
"@popperjs/core": "^2.11.6",
"@vitejs/plugin-vue": "^4.5.0",
"axios": "^1.6.4",
"bootstrap": "^5.2.3",
"laravel-vite-plugin": "^1.0",
"sass": "^1.56.1",
"vite": "^5.0",
"vue": "^3.2.37"
}
},
"node_modules/@babel/parser": {
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
"integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
"dev": true,
"license": "MIT",
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
"integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"dev": true,
"license": "MIT"
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"dev": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz",
"integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz",
"integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true,
"license": "MIT"
},
"node_modules/@vitejs/plugin-vue": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz",
"integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"peerDependencies": {
"vite": "^4.0.0 || ^5.0.0",
"vue": "^3.2.25"
}
},
"node_modules/@vue/compiler-core": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.26.tgz",
"integrity": "sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.24.4",
"@vue/shared": "3.4.26",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.26.tgz",
"integrity": "sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.4.26",
"@vue/shared": "3.4.26"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.26.tgz",
"integrity": "sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.24.4",
"@vue/compiler-core": "3.4.26",
"@vue/compiler-dom": "3.4.26",
"@vue/compiler-ssr": "3.4.26",
"@vue/shared": "3.4.26",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.10",
"postcss": "^8.4.38",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.26.tgz",
"integrity": "sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.4.26",
"@vue/shared": "3.4.26"
}
},
"node_modules/@vue/reactivity": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.26.tgz",
"integrity": "sha512-E/ynEAu/pw0yotJeLdvZEsp5Olmxt+9/WqzvKff0gE67tw73gmbx6tRkiagE/eH0UCubzSlGRebCbidB1CpqZQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/shared": "3.4.26"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.26.tgz",
"integrity": "sha512-AFJDLpZvhT4ujUgZSIL9pdNcO23qVFh7zWCsNdGQBw8ecLNxOOnPcK9wTTIYCmBJnuPHpukOwo62a2PPivihqw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.4.26",
"@vue/shared": "3.4.26"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.26.tgz",
"integrity": "sha512-UftYA2hUXR2UOZD/Fc3IndZuCOOJgFxJsWOxDkhfVcwLbsfh2CdXE2tG4jWxBZuDAs9J9PzRTUFt1PgydEtItw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/runtime-core": "3.4.26",
"@vue/shared": "3.4.26",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.26.tgz",
"integrity": "sha512-xoGAqSjYDPGAeRWxeoYwqJFD/gw7mpgzOvSxEmjWaFO2rE6qpbD1PC172YRpvKhrihkyHJkNDADFXTfCyVGhKw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-ssr": "3.4.26",
"@vue/shared": "3.4.26"
},
"peerDependencies": {
"vue": "3.4.26"
}
},
"node_modules/@vue/shared": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.26.tgz",
"integrity": "sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ==",
"dev": true,
"license": "MIT"
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"dev": true,
"license": "MIT"
},
"node_modules/axios": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
"integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/bootstrap": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"license": "MIT",
"peerDependencies": {
"@popperjs/core": "^2.11.8"
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
"license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"dev": true,
"license": "MIT"
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/esbuild": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
"integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.20.2",
"@esbuild/android-arm": "0.20.2",
"@esbuild/android-arm64": "0.20.2",
"@esbuild/android-x64": "0.20.2",
"@esbuild/darwin-arm64": "0.20.2",
"@esbuild/darwin-x64": "0.20.2",
"@esbuild/freebsd-arm64": "0.20.2",
"@esbuild/freebsd-x64": "0.20.2",
"@esbuild/linux-arm": "0.20.2",
"@esbuild/linux-arm64": "0.20.2",
"@esbuild/linux-ia32": "0.20.2",
"@esbuild/linux-loong64": "0.20.2",
"@esbuild/linux-mips64el": "0.20.2",
"@esbuild/linux-ppc64": "0.20.2",
"@esbuild/linux-riscv64": "0.20.2",
"@esbuild/linux-s390x": "0.20.2",
"@esbuild/linux-x64": "0.20.2",
"@esbuild/netbsd-x64": "0.20.2",
"@esbuild/openbsd-x64": "0.20.2",
"@esbuild/sunos-x64": "0.20.2",
"@esbuild/win32-arm64": "0.20.2",
"@esbuild/win32-ia32": "0.20.2",
"@esbuild/win32-x64": "0.20.2"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true,
"license": "MIT"
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dev": true,
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/immutable": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
"integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==",
"dev": true,
"license": "MIT"
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/laravel-vite-plugin": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.0.2.tgz",
"integrity": "sha512-Mcclml10khYzBVxDwJro8wnVDwD4i7XOSEMACQNnarvTnHjrjXLLL+B/Snif2wYAyElsOqagJZ7VAinb/2vF5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"picocolors": "^1.0.0",
"vite-plugin-full-reload": "^1.1.0"
},
"bin": {
"clean-orphaned-assets": "bin/clean.js"
},
"engines": {
"node": "^18.0.0 || >=20.0.0"
},
"peerDependencies": {
"vite": "^5.0.0"
}
},
"node_modules/magic-string": {
"version": "0.30.10",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
"integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/postcss": {
"version": "8.4.38",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true,
"license": "MIT"
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=8.10.0"
}
},
"node_modules/remixicon": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/remixicon/-/remixicon-4.2.0.tgz",
"integrity": "sha512-MF5wApNveRh3n0iMVM+lr2nSWrj/rBbSD2eWapuD9ReYRGs5naAUR1BqVBCHGqm286FIS6zwwmUf96QjHQ9l4w==",
"license": "Apache-2.0"
},
"node_modules/rollup": {
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz",
"integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.5"
},
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.17.2",
"@rollup/rollup-android-arm64": "4.17.2",
"@rollup/rollup-darwin-arm64": "4.17.2",
"@rollup/rollup-darwin-x64": "4.17.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.17.2",
"@rollup/rollup-linux-arm-musleabihf": "4.17.2",
"@rollup/rollup-linux-arm64-gnu": "4.17.2",
"@rollup/rollup-linux-arm64-musl": "4.17.2",
"@rollup/rollup-linux-powerpc64le-gnu": "4.17.2",
"@rollup/rollup-linux-riscv64-gnu": "4.17.2",
"@rollup/rollup-linux-s390x-gnu": "4.17.2",
"@rollup/rollup-linux-x64-gnu": "4.17.2",
"@rollup/rollup-linux-x64-musl": "4.17.2",
"@rollup/rollup-win32-arm64-msvc": "4.17.2",
"@rollup/rollup-win32-ia32-msvc": "4.17.2",
"@rollup/rollup-win32-x64-msvc": "4.17.2",
"fsevents": "~2.3.2"
}
},
"node_modules/sass": {
"version": "1.76.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.76.0.tgz",
"integrity": "sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==",
"dev": true,
"license": "MIT",
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
},
"bin": {
"sass": "sass.js"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/three": {
"version": "0.150.0",
"resolved": "https://registry.npmjs.org/three/-/three-0.150.0.tgz",
"integrity": "sha512-12oqqBZom9fb5HtX3rD8qPVnamojuiN5Os7r0x8s3HQ+WHRwnEyzl2XU3aEKocsDkG++rkE9+HWzx77O59NXtw==",
"license": "MIT"
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/vazirmatn": {
"version": "33.0.3",
"resolved": "https://registry.npmjs.org/vazirmatn/-/vazirmatn-33.0.3.tgz",
"integrity": "sha512-fbjNc0CMjazZpIegWzz9OHGzI1APFboT+x7ZecXlUCtDe/nkyx7gtCTZnWS/+eeXG7fbfXymCPKJI8EsnM3iqw==",
"license": "OFL"
},
"node_modules/vite": {
"version": "5.2.11",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz",
"integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.20.1",
"postcss": "^8.4.38",
"rollup": "^4.13.0"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": "^18.0.0 || >=20.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
},
"peerDependencies": {
"@types/node": "^18.0.0 || >=20.0.0",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
"stylus": "*",
"sugarss": "*",
"terser": "^5.4.0"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
"less": {
"optional": true
},
"lightningcss": {
"optional": true
},
"sass": {
"optional": true
},
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"terser": {
"optional": true
}
}
},
"node_modules/vite-plugin-full-reload": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.1.0.tgz",
"integrity": "sha512-3cObNDzX6DdfhD9E7kf6w2mNunFpD7drxyNgHLw+XwIYAgb+Xt16SEXo0Up4VH+TMf3n+DSVJZtW2POBGcBYAA==",
"dev": true,
"license": "MIT",
"dependencies": {
"picocolors": "^1.0.0",
"picomatch": "^2.3.1"
}
},
"node_modules/vue": {
"version": "3.4.26",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.26.tgz",
"integrity": "sha512-bUIq/p+VB+0xrJubaemrfhk1/FiW9iX+pDV+62I/XJ6EkspAO9/DXEjbDFoe8pIfOZBqfk45i9BMc41ptP/uRg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.4.26",
"@vue/compiler-sfc": "3.4.26",
"@vue/runtime-dom": "3.4.26",
"@vue/server-renderer": "3.4.26",
"@vue/shared": "3.4.26"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
}
}
}

@ -16,8 +16,10 @@
"vue": "^3.2.37"
},
"dependencies": {
"leaflet": "^1.9.4",
"remixicon": "^4.2.0",
"three": "0.150.0",
"vazirmatn": "^33.0.3"
"vazirmatn": "^33.0.3",
"vue-toast-notification": "^3.1.2"
}
}

@ -63,6 +63,9 @@ app.component('tag-input', TagInput);
import SliderData from "./components/SliderData.vue";
app.component('slider-data', SliderData);
import AddressInput from "./components/AddressInput.vue";
app.component('address-input', AddressInput);
/**
* The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue

@ -0,0 +1,424 @@
<template>
<div id="address-input">
<table class="w-100">
<tr v-for="ad in addresses">
<td>
{{ ad.address }}
</td>
<td class="py-1">
<div class="btn btn-outline-danger btn-sm float-end mx-2" @click="removing(ad.id)">
<i class="ri-close-line"></i>
</div>
<div class="btn btn-outline-primary btn-sm float-end" @click="editing(ad)">
<i class="ri-edit-2-line"></i>
</div>
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @click="adding">
<i class="ri-add-line"></i>
</button>
<div id="address-modal" v-if="modal" @click.self="modal = false">
<div class="card">
<div class="card-header">
Address editor <!-- WIP Translate -->
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<label for="st">
State: <!-- WIP Translate -->
</label>
<select @change="updateState" class="form-control" v-model="state_id" id="st">
<option :data-lat="s.lat" :data-lng="s.lng" :value="s.id" v-for="s in states">
{{ s.name }}
</option>
</select>
</div>
<div class="col-md-6">
<label for="st">
City: <!-- WIP Translate -->
</label>
<select @change="updateCity" class="form-control" v-model="city_id" id="st">
<option :value="c.id" v-for="c in cities"> {{ c.name }}</option>
</select>
</div>
<div class="col-12 my-3">
<div ref="mapContainer" :style="'height: 300px;'+mapStyle"></div>
</div>
<div class="col-12">
<textarea rows="2" class="form-control" placeholder="Address" v-model="address"></textarea>
<!-- WIP Translate -->
</div>
<div class="col-12">
<label for="zip">
Postcode: <!-- WIP Translate -->
</label>
<input type="text" class="form-control" v-model="zip">
</div>
</div>
</div>
<div class="card-footer">
<button class="btn btn-primary w-100" type="button" @click="save">
<i class="ri-save-2-line"></i>
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import {useToast} from 'vue-toast-notification';
const $toast = useToast();
export default {
name: "address-input",
components: {},
data: () => {
return {
id: null,
action: 'add',
modal: false,
addresses: [],
states: [],
cities: [],
state_id: null,
city_id: null,
map: null,
marker: null,
zoom: 10,
address: '',
zip: '',
lat: null,
lng: null,
}
},
props: {
listLink: {
type: String,
required: true,
},
addLink: {
type: String,
required: true,
},
updateLink: {
type: String,
required: true,
},
remLink: {
type: String,
required: true,
},
stateLink: {
type: String,
required: true,
},
citiesLink: {
type: String,
required: true,
},
darkMode: {
type: Boolean,
default: false,
}
},
async mounted() {
try {
let res = await axios.get(this.stateLink);
this.states = res.data.data;
// console.log(res.data);
} catch (e) {
$toast.error(e.message);
}
await this.updateList();
// await this.initMap();
// if (this.states[0].lat != null && this.states[0].lng != null){
// this.changeMapCenter(this.states[0].lat,this.states[0].lng)
// }
},
computed: {
mapStyle() {
if (this.darkMode) {
return 'filter: invert(100%) hue-rotate(120deg) brightness(95%) contrast(90%);';
}
return '';
}
},
methods: {
async save() {
let canSave = true;
if (this.state_id == null) {
$toast.error("State is required"); // WIP translate
canSave = false;
}
if (this.city_id == null) {
$toast.error("City is required"); // WIP translate
canSave = false;
}
if (this.address.length < 10) {
$toast.error("Address is required"); // WIP translate
canSave = false;
}
if (this.zip.length < 5) {
$toast.error("Post code is required"); // WIP translate
canSave = false;
}
if (!canSave) {
return false;
}
if (this.action == 'add') {
let data = {
address: this.address,
state_id: this.state_id,
city_id: this.city_id,
zip: this.zip,
lat: this.lat,
lng: this.lng
};
try {
let r = await axios.post(this.addLink, data);
if (r.data.OK) {
this.addresses = r.data.list;
$toast.success(r.data.message);
this.modal = false;
}
} catch (e) {
$toast.error('err!' + e.message);
}
} else {
let data = {
address: this.address,
state_id: this.state_id,
city_id: this.city_id,
zip: this.zip,
lat: this.lat,
lng: this.lng
};
try {
const url = this.updateLink + '/' + this.id;
let r = await axios.post(url, data);
if (r.data.OK) {
$toast.success(r.data.message);
await this.updateList();
this.modal = false;
}
} catch (e) {
$toast.error('err!' + e.message);
}
}
},
showModal() {
this.modal = true;
setTimeout(() => {
this.initMap();
}, 50);
},
async removing(id) {
if (!confirm('Sure?')) { //WIP: translate
return;
}
const url = this.remLink + '/' + id;
try {
let r = await axios.get(url);
if (r.data.OK) {
$toast.success(r.data.message);
this.updateList();
}
} catch(e) {
$toast.error('err!' + e.message);
}
},
async editing(dt) {
this.showModal();
this.action = 'edit';
this.id = dt.id;
this.lat = dt.lat;
this.lng = dt.lng;
this.zip = dt.zip;
this.address = dt.address;
this.state_id = dt.state_id;
await this.updateState();
this.city_id = dt.city_id;
if (this.lng != null && this.lat != null) {
this.zoom = 16;
setTimeout(() => {
this.changeMapCenter(this.lat, this.lng);
this.marker = L.marker({lat:this.lat, lng: this.lng}).addTo(this.map);
}, 100);
}
},
adding() {
this.action = 'add';
this.address = '';
this.zip = '';
this.state_id = null;
this.showModal();
},
initMap() {
this.map = L.map(this.$refs.mapContainer).setView([35.83266000, 50.99155000], 10);
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.getAddress(e.latlng);
this.lat = e.latlng.lat;
this.lng = e.latlng.lng;
},
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
},
async updateList() {
try {
let res = await axios.get(this.listLink);
this.addresses = res.data;
} catch (e) {
$toast.error('err!' + e.message);
}
},
async updateState() {
for (const st of this.states) {
if (st.id == this.state_id) {
// console.log(st);
if (st.lat != null && st.lng != null) {
this.zoom = 10;
this.changeMapCenter(st.lat, st.lng)
}
break;
}
}
try {
let res = await axios.get(this.citiesLink + '/' + this.state_id);
this.cities = res.data.data;
} catch (e) {
$toast.error('err!' + e.message);
}
},
async updateCity() {
for (const c of this.cities) {
if (c.id == this.city_id) {
if (c.lat != null && c.lng != null) {
this.zoom = 12;
this.changeMapCenter(c.lat, c.lng)
}
break;
}
}
},
getAddress(latlng) {
const url = `https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${latlng.lat}&lon=${latlng.lng}&addressdetails=1&accept-language=en`;
fetch(url)
.then(response => response.json())
.then(data => {
const address = this.formatAddress(data.address);
this.address = address;
})
.catch(error => {
$toast.error('err!' + error.message);
});
},
formatAddress(addressData) {
let formattedAddress = '';
if (addressData.road) {
formattedAddress += addressData.road;
}
if (addressData.neighbourhood) {
formattedAddress += addressData.neighbourhood;
}
//
// if (addressData.house_number) {
// formattedAddress += ` ${addressData.house_number}`;
// }
//
if (addressData.postcode) {
// formattedAddress += `, ${addressData.postcode}`;
let x = addressData.postcode.split('-');
this.zip = x.join('');
}
if (addressData.city) {
formattedAddress += `, ${addressData.city}`;
}
//
// if (addressData.country) {
// formattedAddress += `, ${addressData.country}`;
// }
return formattedAddress;
},
}
}
</script>
<style scoped>
#address-input {
padding: 0 .75rem 1rem;
}
#address-modal {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
backdrop-filter: blur(4px);
background: #ffffff33;
z-index: 9;
display: flex;
align-items: center;
justify-content: center;
}
#address-modal .card {
max-width: 900px;
width: 100%;
}
</style>

@ -12,4 +12,21 @@ document.querySelectorAll('.delete-confirm')?.forEach(function (el) {
e.preventDefault();
}
});
})
});
window.findUrl = function (name,item = null) {
for (var i = 0; i < window.routesList.length; i++) {
if (window.routesList[i].name === name) {
if (item != null){
return window.routesList[i].url.split('{item}').join(item);
}else{
return window.routesList[i].url;
}
}
}
return null;
}

@ -1,6 +1,7 @@
// Fonts
@import 'vazirmatn/Vazirmatn-font-face.css';
@import "remixicon/fonts/remixicon.css";
@import "vue-toast-notification/dist/theme-bootstrap.css";
// Variables
@import 'panel/variables';

@ -0,0 +1,147 @@
@extends('admin.templates.panel-form-template')
@section('title')
@if(isset($item))
{{__("Edit customer")}} [{{$item->name}}]
@else
{{__("Add new customer")}}
@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>
@if(isset($item))
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-user-location-line"></i>
{{__("Addresses")}}
</h3>
<address-input
list-link="{{route('admin.address.customer',$item->id)}}"
add-link="{{route('admin.address.store',$item->id)}}"
update-link="{{route('admin.address.update','')}}"
rem-link="{{route('admin.address.destroy','')}}"
state-link="{{route('v1.state.index')}}"
cities-link="{{route('v1.state.show','')}}"
:dark-mode="true"
></address-input>
</div>
@endif
</div>
<div class="col-lg-9 ps-xl-1 ps-xxl-1">
<div class="general-form ">
<h1>
@if(isset($item))
{{__("Edit customer")}} [{{$item->name}}]
@else
{{__("Add new customer")}}
@endif
</h1>
<div class="row">
<div class="col-md-4 mt-3">
<div class="form-group">
<label for="name">
{{__('Name')}}
</label>
<input name="name" type="text" class="form-control @error('name') is-invalid @enderror"
placeholder="{{__('Name')}}" value="{{old('name',$item->name??null)}}"/>
</div>
</div>
<div class="col-md-4 mt-3">
<div class="form-group">
<label for="email">
{{__('Email')}}
</label>
<input name="email" type="email" class="form-control @error('email') is-invalid @enderror"
placeholder="{{__('Email')}}" value="{{old('email',$item->email??null)}}"/>
</div>
</div>
<div class="col-md-4 mt-3">
<div class="form-group">
<label for="credit">
{{__('Credit')}}
</label>
<currency-input :xvalue="{{old('credit',$item->credit??0)}}"
name="credit" xid="credit"
@error('credit') :err="true" @enderror>
</currency-input>
</div>
</div>
<div class="col-md-4 mt-3">
<div class="form-group">
<label for="mobile">
{{__('Mobile')}}
</label>
<input name="mobile" type="text" class="form-control @error('mobile') is-invalid @enderror"
placeholder="{{__('Mobile')}}" value="{{old('mobile',$item->mobile??null)}}"
min-length="10"/>
</div>
</div>
<div class="col-md-3 mt-3">
<div class="form-group">
<label for="password">
{{__('Password')}}
</label>
<input name="password" type="password"
class="form-control @error('password') is-invalid @enderror"
placeholder="{{__('Password')}}" value="{{old('password',''??null)}}"/>
</div>
</div>
<div class="col-md-3 mt-3">
<div class="form-group">
<label for="password_confirmation">
{{__('password repeat')}}
</label>
<input name="password_confirmation" type="password"
class="form-control @error('password_confirmation') is-invalid @enderror"
placeholder="{{__('password repeat')}}"
value="{{old('password_confirmation',$item->password_confirmation??null)}}"/>
</div>
</div>
<div class="col-md-2 mt-3">
<div class="form-check form-switch pt-4 mt-2">
<input class="form-check-input @error('colleague') is-invalid @enderror"
type="checkbox" id="colleague" name="colleague"
@if (isset($item) && $item->colleague)
checked
@endif>
<label class="form-check-label" for="colleague">{{__("Colleague")}}</label>
</div>
</div>
<div class="col-md-12 mt-3">
<div class="form-group">
<label for="description">
{{__('Description')}}
</label>
<textarea name="description" id="description" type="password"
class="form-control @error('description') is-invalid @enderror"
placeholder="{{__('Description')}}">{{old('description',$item->description??null)}}</textarea>
</div>
</div>
<div class="col-md-12">
<label> &nbsp;</label>
<input name="" 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>
{{__("Customers list")}}
@endsection
@section('title')
{{__("Customers list")}} -
@endsection
@section('filter')
{{-- Other filters --}}
@endsection
@section('bulk')
{{-- <option value="-"> - </option> --}}
@endsection

@ -1,6 +1,7 @@
@yield('js-content')
<script type="text/javascript">
var xupload = "{{route('admin.ckeditor.upload', ['_token' => csrf_token() ])}}";
window.routesList = @json(getAdminRoutes());
</script>
</body>
</html>

@ -13,7 +13,7 @@
</a>
<ul id="card">
<li>
<a href="">
<a href="{{route('admin.customer.index')}}">
<i class="ri-team-fill"></i>
{{__('Customers')}}

@ -0,0 +1,38 @@
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Route::get('', function () {
return 'xshop api:'.config('app.name');
});
Route::get('/clear', function () {
if (!auth()->check()){
return abort(403);
}
Artisan::call('cache:clear');
Artisan::call('config:clear');
Artisan::call('config:cache');
Artisan::call('view:clear');
Artisan::call('route:clear');
return "Cleared!";
});
Route::prefix('v1')->name('v1.')->group(
function () {
Route::get('', function () {
return 'xShop api v1';
});
Route::get('states', [\App\Http\Controllers\Api\StateController::class,'index'])->name('state.index');
Route::get('state/{state}', [\App\Http\Controllers\Api\StateController::class,'show'])->name('state.show');
});

@ -104,6 +104,19 @@ Route::prefix(config('app.panel.prefix'))->name('admin.')->group(
Route::post('bulk', [\App\Http\Controllers\Admin\AdvController::class, "bulk"])->name('bulk');
Route::get('trashed', [\App\Http\Controllers\Admin\AdvController::class, "trashed"])->name('trashed');
});
Route::prefix('customers')->name('customer.')->group(
function () {
Route::get('', [\App\Http\Controllers\Admin\CustomerController::class, 'index'])->name('index');
Route::get('create', [\App\Http\Controllers\Admin\CustomerController::class, 'create'])->name('create');
Route::post('store', [\App\Http\Controllers\Admin\CustomerController::class, 'store'])->name('store');
Route::get('show/{item}', [\App\Http\Controllers\Admin\CustomerController::class, 'show'])->name('show');
Route::get('edit/{item}', [\App\Http\Controllers\Admin\CustomerController::class, 'edit'])->name('edit');
Route::post('update/{item}', [\App\Http\Controllers\Admin\CustomerController::class, 'update'])->name('update');
Route::get('delete/{item}', [\App\Http\Controllers\Admin\CustomerController::class, 'destroy'])->name('destroy');
Route::get('restore/{item}', [\App\Http\Controllers\Admin\CustomerController::class, 'restore'])->name('restore');
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('galleries')->name('gallery.')->group(
function () {
Route::get('', [\App\Http\Controllers\Admin\GalleryController::class, 'index'])->name('index');
@ -128,5 +141,17 @@ Route::prefix(config('app.panel.prefix'))->name('admin.')->group(
Route::get('delete/{item}', [\App\Http\Controllers\Admin\SliderController::class, 'destroy'])->name('destroy');
Route::post('bulk', [\App\Http\Controllers\Admin\SliderController::class, "bulk"])->name('bulk');
});
Route::prefix('addresses')->name('address.')->group(
function () {
Route::get('customer/{item}', [\App\Http\Controllers\Admin\AddressController::class, 'customer'])->name('customer');
Route::post('add/{item}', [\App\Http\Controllers\Admin\AddressController::class, 'store'])->name('store');
Route::post('update/{item}', [\App\Http\Controllers\Admin\AddressController::class, 'update'])->name('update');
Route::get('destroy/{item}', [\App\Http\Controllers\Admin\AddressController::class, 'destroy'])->name('destroy');
});
});
});
Route::get('test',function (){
return \App\Helpers\PersianFaker::color();
});

@ -4,7 +4,7 @@
"@babel/parser@^7.24.4":
version "7.24.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz"
integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==
"@esbuild/aix-ppc64@0.20.2":
@ -89,7 +89,7 @@
"@esbuild/linux-x64@0.20.2":
version "0.20.2"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff"
resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz"
integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==
"@esbuild/netbsd-x64@0.20.2":
@ -124,12 +124,12 @@
"@jridgewell/sourcemap-codec@^1.4.15":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@popperjs/core@^2.11.6":
version "2.11.8"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz"
integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
"@rollup/rollup-android-arm-eabi@4.17.2":
@ -189,12 +189,12 @@
"@rollup/rollup-linux-x64-gnu@4.17.2":
version "4.17.2"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz#b521d271798d037ad70c9f85dd97d25f8a52e811"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz"
integrity sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==
"@rollup/rollup-linux-x64-musl@4.17.2":
version "4.17.2"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz#9254019cc4baac35800991315d133cc9fd1bf385"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz"
integrity sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==
"@rollup/rollup-win32-arm64-msvc@4.17.2":
@ -214,17 +214,17 @@
"@types/estree@1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@vitejs/plugin-vue@^4.5.0":
version "4.6.2"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz#057d2ded94c4e71b94e9814f92dcd9306317aa46"
resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz"
integrity sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==
"@vue/compiler-core@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.26.tgz#d507886520e83a6f8339ed55ed0b2b5d84b44b73"
resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.26.tgz"
integrity sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ==
dependencies:
"@babel/parser" "^7.24.4"
@ -235,7 +235,7 @@
"@vue/compiler-dom@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.26.tgz#acc7b788b48152d087d4bb9e655b795e3dbec554"
resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.26.tgz"
integrity sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA==
dependencies:
"@vue/compiler-core" "3.4.26"
@ -243,7 +243,7 @@
"@vue/compiler-sfc@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.26.tgz#c679f206829954c3c078d8a9be76d0098b8377ae"
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.26.tgz"
integrity sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw==
dependencies:
"@babel/parser" "^7.24.4"
@ -258,7 +258,7 @@
"@vue/compiler-ssr@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.26.tgz#22842d8adfff972d87bb798b8d496111f7f814b5"
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.26.tgz"
integrity sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ==
dependencies:
"@vue/compiler-dom" "3.4.26"
@ -266,14 +266,14 @@
"@vue/reactivity@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.26.tgz#1191f543809d4c93e5b3e842ba83022350a3f205"
resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.26.tgz"
integrity sha512-E/ynEAu/pw0yotJeLdvZEsp5Olmxt+9/WqzvKff0gE67tw73gmbx6tRkiagE/eH0UCubzSlGRebCbidB1CpqZQ==
dependencies:
"@vue/shared" "3.4.26"
"@vue/runtime-core@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.26.tgz#51ee971cb700370a67e5a510c4a84eff7491d658"
resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.26.tgz"
integrity sha512-AFJDLpZvhT4ujUgZSIL9pdNcO23qVFh7zWCsNdGQBw8ecLNxOOnPcK9wTTIYCmBJnuPHpukOwo62a2PPivihqw==
dependencies:
"@vue/reactivity" "3.4.26"
@ -281,7 +281,7 @@
"@vue/runtime-dom@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.26.tgz#179aa7c8dc964112e6d096bc8ec5f361111009a1"
resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.26.tgz"
integrity sha512-UftYA2hUXR2UOZD/Fc3IndZuCOOJgFxJsWOxDkhfVcwLbsfh2CdXE2tG4jWxBZuDAs9J9PzRTUFt1PgydEtItw==
dependencies:
"@vue/runtime-core" "3.4.26"
@ -290,7 +290,7 @@
"@vue/server-renderer@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.26.tgz#6d0c6b0366bfe0232579aea00e3ff6784e5a1c60"
resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.26.tgz"
integrity sha512-xoGAqSjYDPGAeRWxeoYwqJFD/gw7mpgzOvSxEmjWaFO2rE6qpbD1PC172YRpvKhrihkyHJkNDADFXTfCyVGhKw==
dependencies:
"@vue/compiler-ssr" "3.4.26"
@ -298,12 +298,12 @@
"@vue/shared@3.4.26":
version "3.4.26"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.26.tgz#f17854fb1faf889854aed4b23b60e86a8cab6403"
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.4.26.tgz"
integrity sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ==
anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz"
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
dependencies:
normalize-path "^3.0.0"
@ -311,12 +311,12 @@ anymatch@~3.1.2:
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
axios@^1.6.4:
version "1.6.8"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66"
resolved "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz"
integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==
dependencies:
follow-redirects "^1.15.6"
@ -325,24 +325,24 @@ axios@^1.6.4:
binary-extensions@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
bootstrap@^5.2.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.3.tgz#de35e1a765c897ac940021900fcbb831602bac38"
resolved "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz"
integrity sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==
braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
dependencies:
fill-range "^7.0.1"
"chokidar@>=3.0.0 <4.0.0":
version "3.6.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz"
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
dependencies:
anymatch "~3.1.2"
@ -357,29 +357,29 @@ braces@~3.0.2:
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
entities@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
esbuild@^0.20.1:
version "0.20.2"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz"
integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==
optionalDependencies:
"@esbuild/aix-ppc64" "0.20.2"
@ -408,24 +408,24 @@ esbuild@^0.20.1:
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
dependencies:
to-regex-range "^5.0.1"
follow-redirects@^1.15.6:
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
@ -439,90 +439,95 @@ fsevents@~2.3.2, fsevents@~2.3.3:
glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
immutable@^4.0.0:
version "4.3.5"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0"
resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz"
integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==
is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
dependencies:
binary-extensions "^2.0.0"
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-glob@^4.0.1, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
laravel-vite-plugin@^1.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/laravel-vite-plugin/-/laravel-vite-plugin-1.0.2.tgz#97575181a1f870532b39ab3b423b53f01385feba"
resolved "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.0.2.tgz"
integrity sha512-Mcclml10khYzBVxDwJro8wnVDwD4i7XOSEMACQNnarvTnHjrjXLLL+B/Snif2wYAyElsOqagJZ7VAinb/2vF5g==
dependencies:
picocolors "^1.0.0"
vite-plugin-full-reload "^1.1.0"
leaflet@^1.9.4:
version "1.9.4"
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.4.tgz#23fae724e282fa25745aff82ca4d394748db7d8d"
integrity sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==
magic-string@^0.30.10:
version "0.30.10"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e"
resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz"
integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.15"
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
nanoid@^3.3.7:
version "3.3.7"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
postcss@^8.4.38:
version "8.4.38"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz"
integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==
dependencies:
nanoid "^3.3.7"
@ -531,24 +536,24 @@ postcss@^8.4.38:
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
dependencies:
picomatch "^2.2.1"
remixicon@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/remixicon/-/remixicon-4.2.0.tgz#2df60b1764b11bb363f796b827ed8e03eab031c4"
resolved "https://registry.npmjs.org/remixicon/-/remixicon-4.2.0.tgz"
integrity sha512-MF5wApNveRh3n0iMVM+lr2nSWrj/rBbSD2eWapuD9ReYRGs5naAUR1BqVBCHGqm286FIS6zwwmUf96QjHQ9l4w==
rollup@^4.13.0:
version "4.17.2"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.17.2.tgz#26d1785d0144122277fdb20ab3a24729ae68301f"
resolved "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz"
integrity sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==
dependencies:
"@types/estree" "1.0.5"
@ -573,7 +578,7 @@ rollup@^4.13.0:
sass@^1.56.1:
version "1.76.0"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.76.0.tgz#fe15909500735ac154f0dc7386d656b62b03987d"
resolved "https://registry.npmjs.org/sass/-/sass-1.76.0.tgz"
integrity sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==
dependencies:
chokidar ">=3.0.0 <4.0.0"
@ -582,29 +587,29 @@ sass@^1.56.1:
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
three@0.150.0:
version "0.150.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.150.0.tgz#38a324c3976e07799671d06d99f01b02a2fe65c6"
resolved "https://registry.npmjs.org/three/-/three-0.150.0.tgz"
integrity sha512-12oqqBZom9fb5HtX3rD8qPVnamojuiN5Os7r0x8s3HQ+WHRwnEyzl2XU3aEKocsDkG++rkE9+HWzx77O59NXtw==
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
vazirmatn@^33.0.3:
version "33.0.3"
resolved "https://registry.yarnpkg.com/vazirmatn/-/vazirmatn-33.0.3.tgz#d4617dfb0fa97c6aaeb35ab19fa713f0a04ffc21"
resolved "https://registry.npmjs.org/vazirmatn/-/vazirmatn-33.0.3.tgz"
integrity sha512-fbjNc0CMjazZpIegWzz9OHGzI1APFboT+x7ZecXlUCtDe/nkyx7gtCTZnWS/+eeXG7fbfXymCPKJI8EsnM3iqw==
vite-plugin-full-reload@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/vite-plugin-full-reload/-/vite-plugin-full-reload-1.1.0.tgz#ca6fa32631024a459ea9e5613dd4c0ff0f3b7995"
resolved "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.1.0.tgz"
integrity sha512-3cObNDzX6DdfhD9E7kf6w2mNunFpD7drxyNgHLw+XwIYAgb+Xt16SEXo0Up4VH+TMf3n+DSVJZtW2POBGcBYAA==
dependencies:
picocolors "^1.0.0"
@ -612,7 +617,7 @@ vite-plugin-full-reload@^1.1.0:
vite@^5.0:
version "5.2.11"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.11.tgz#726ec05555431735853417c3c0bfb36003ca0cbd"
resolved "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz"
integrity sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==
dependencies:
esbuild "^0.20.1"
@ -621,9 +626,14 @@ vite@^5.0:
optionalDependencies:
fsevents "~2.3.3"
vue-toast-notification@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/vue-toast-notification/-/vue-toast-notification-3.1.2.tgz#55106acc4f2c17ecf84468ee9435b97fc7106748"
integrity sha512-oNRL/W9aaHoeScp+iTIW7k09vM16/+8aptp2maa+7qTB43JuxmAgKdXKFYtf+uvSNOYYq2BIWgLCeJ61pwom/A==
vue@^3.2.37:
version "3.4.26"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.26.tgz#936c97e37672c737705d7bdfa62c31af18742269"
resolved "https://registry.npmjs.org/vue/-/vue-3.4.26.tgz"
integrity sha512-bUIq/p+VB+0xrJubaemrfhk1/FiW9iX+pDV+62I/XJ6EkspAO9/DXEjbDFoe8pIfOZBqfk45i9BMc41ptP/uRg==
dependencies:
"@vue/compiler-dom" "3.4.26"

Loading…
Cancel
Save