optimized client command

added post icon simple
pull/44/head
A1Gard 4 months ago
parent b45f3cbce7
commit 8ae1915297

@ -29,16 +29,22 @@ class clientAssetGenerator extends Command
{ {
// make gfx variable // make gfx variable
$gfxes = gfx(); $gfxes = gfx();
$vars['xshop-background'] = $gfxes['background'] ?? '#000000'; $vars['xshop-background'] = $gfxes['background'] ?? '#000000';
$vars['xshop-primary'] = $gfxes['primary'] ?? '#6e0000'; $vars['xshop-primary'] = $gfxes['primary'] ?? '#6e0000';
$vars['xshop-diff'] = getGrayscaleTextColor($gfxes['primary']) ?? '#6e0000';
$vars['xshop-secondary'] = $gfxes['secondary'] ?? '#ff0000'; $vars['xshop-secondary'] = $gfxes['secondary'] ?? '#ff0000';
$vars['xshop-text'] = $gfxes['text'] ?? '#111111'; $vars['xshop-text'] = $gfxes['text'] ?? '#111111';
$vars['border-radius'] = $gfxes['border-radius'] ?? '7px'; $vars['xshop-border-radius'] = $gfxes['border-radius'] ?? '7px';
$vars['xshop-shadow'] = $gfxes['shadow'] ?? '2px 2px 4px #777777'; $vars['xshop-shadow'] = $gfxes['shadow'] ?? '2px 2px 4px #777777';
// prepare client.scss and add gfx variable // prepare client.scss and add gfx variable
$js = "// PLEASE DO NOT EDIT THIS FILE, \n// IF YOU WANT ADD ANY CODE CREATE NEW JS INTO client-custom" . PHP_EOL; $js = "// PLEASE DO NOT EDIT THIS FILE, \n// IF YOU WANT ADD ANY CODE CREATE NEW JS INTO client-custom" . PHP_EOL;
$variables = "// PLEASE DO NOT EDIT THIS FILE, \n// IF YOU WANT ADD ANY CODE CREATE NEW SCSS INTO client-custom" . PHP_EOL; $variables = "// PLEASE DO NOT EDIT THIS FILE, \n// IF YOU WANT ADD ANY CODE CREATE NEW SCSS INTO client-custom" . PHP_EOL;
foreach ($vars as $k => $var) {
$variables .= '$'."$k:$var;" . PHP_EOL;
}
$variables .= ":root{" . PHP_EOL; $variables .= ":root{" . PHP_EOL;
foreach ($vars as $k => $var) { foreach ($vars as $k => $var) {
$variables .= "--$k:$var;" . PHP_EOL; $variables .= "--$k:$var;" . PHP_EOL;

@ -16,6 +16,6 @@ class Handle
} }
public static function onMount(Part $part = null) public static function onMount(Part $part = null)
{ {
return $part;
} }
} }

@ -2,6 +2,7 @@
use App\Helpers; use App\Helpers;
use App\Models\Setting; use App\Models\Setting;
use App\Models\Group;
use App\Models\Area; use App\Models\Area;
use App\Models\Part; use App\Models\Part;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
@ -684,17 +685,18 @@ function nestedWithData($items, $parent_id = null)
* @param $areaName * @param $areaName
* @return \App\Models\Part|false * @return \App\Models\Part|false
*/ */
function hasPart($areaName){ function hasPart($areaName)
$a = Area::where('name',$areaName)->first(); {
if ($a == null){ $a = Area::where('name', $areaName)->first();
if ($a == null) {
return false; return false;
} }
$p = Part::where('area_id',$a->id)->first(); $p = Part::where('area_id', $a->id)->first();
if ($p == null){ if ($p == null) {
return false; return false;
} }
return $p ; return $p;
} }
@ -704,8 +706,9 @@ function hasPart($areaName){
* @param $areaName * @param $areaName
* @return Part[]|\Illuminate\Database\Eloquent\Collection|\LaravelIdea\Helper\App\Models\_IH_Part_C * @return Part[]|\Illuminate\Database\Eloquent\Collection|\LaravelIdea\Helper\App\Models\_IH_Part_C
*/ */
function getParts($areaName){ function getParts($areaName)
$a = Area::where('name',$areaName)->first(); {
$a = Area::where('name', $areaName)->first();
return $a->parts()->orderBy('sort')->get(); return $a->parts()->orderBy('sort')->get();
} }
@ -715,14 +718,61 @@ function getParts($areaName){
* @param $group * @param $group
* @return array * @return array
*/ */
function getSettingsGroup($group){ function getSettingsGroup($group)
{
$result = []; $result = [];
foreach (Setting::where('key','LIKE',$group.'%') foreach (Setting::where('key', 'LIKE', $group . '%')
->whereNotNull('value')->get(['key','value']) as $r){ ->whereNotNull('value')->get(['key', 'value']) as $r) {
if ($r->value != null){ if ($r->value != null) {
$result[substr($r->key,mb_strlen($group))] = $r->value; $result[substr($r->key, mb_strlen($group))] = $r->value;
} }
} }
return $result; return $result;
} }
/**
* get different color by backgroun
* @param $bgColor
* @return string
*/
function getGrayscaleTextColor($bgColor)
{
// Convert the provided background color to RGB
$bgRgb = sscanf($bgColor, "#%02x%02x%02x");
// Calculate the luminance of the background color
$luminance = (0.299 * $bgRgb[0] + 0.587 * $bgRgb[1] + 0.114 * $bgRgb[2]) / 255;
// Determine the best color for text based on luminance
if ($luminance > 0.5) {
$textColor = '#000000'; // Black text
} else {
$textColor = '#ffffff'; // White text
}
return $textColor;
}
/**
* get group by setting key
* @param $key
* @return Group
*/
function getGroupBySetting($key)
{
return Group::where('id', getSetting($key) ?? 1)->first();
}
/**
* get group's posts by setting key
* @param $key
* @param $limit
* @return \App\Models\Post[]|\Illuminate\Database\Eloquent\Collection|\LaravelIdea\Helper\App\Models\_IH_Post_C
*/
function getGroupPostsBySetting($key, $limit = 10)
{
return Group::where('id', getSetting($key) ?? 1)->first()
->posts()->where('status', 1)->limit($limit)->get();
}

@ -12,8 +12,10 @@ class Area extends Model
'ads', 'ads',
'attachment', 'attachment',
'attachments', 'attachments',
'attachmentsList', 'attachments_page',
'card', 'card',
'categories',
'categories_page',
'category', 'category',
'clip', 'clip',
'clips', 'clips',
@ -26,14 +28,20 @@ class Area extends Model
'gallery', 'gallery',
'group', 'group',
'groups', 'groups',
'groups_page',
'index', 'index',
'invoice', 'invoice',
'login', 'login',
'menu', 'menu',
'other',
'parallax', 'parallax',
'post',
'posts',
'posts_page',
'preloader', 'preloader',
'product', 'product',
'products', 'products',
'products_page',
'questions', 'questions',
'search', 'search',
'slider', 'slider',

@ -70,4 +70,9 @@ class Category extends Model
return $this->morphMany(Attachment::class,'attachable'); return $this->morphMany(Attachment::class,'attachable');
} }
public function webUrl(){
return '#';// WIP
return route('');
}
} }

@ -46,5 +46,9 @@ class Clip extends Model
return $this->morphMany(Attachment::class,'attachable'); return $this->morphMany(Attachment::class,'attachable');
} }
public function webUrl(){
return '#';// WIP
return route('');
}
} }

@ -69,4 +69,9 @@ class Gallery extends Model implements HasMedia
public function attachs(){ public function attachs(){
return $this->morphMany(Attachment::class,'attachable'); return $this->morphMany(Attachment::class,'attachable');
} }
public function webUrl(){
return '#';// WIP
return route('');
}
} }

@ -75,4 +75,9 @@ class Group extends Model
public function attachs(){ public function attachs(){
return $this->morphMany(Attachment::class,'attachable'); return $this->morphMany(Attachment::class,'attachable');
} }
public function webUrl(){
return '#';// WIP
return route('');
}
} }

@ -16,4 +16,13 @@ class Part extends Model
$handle::onMount($this); $handle::onMount($this);
return 'segments.'.$this->segment.'.'.$this->part.'.'.$this->part; return 'segments.'.$this->segment.'.'.$this->part.'.'.$this->part;
} }
public function getBladeWithData(){
$className= ucfirst($this->part);
$handle = "\\Resources\\Views\\Segments\\$className";
return ['blade' => 'segments.'.$this->segment.'.'.$this->part.'.'.$this->part, 'data' => $handle::onMount($this)];
}
public function area(){
return $this->belongsTo(Area::class);
}
} }

@ -122,4 +122,9 @@ class Post extends Model implements HasMedia
// 'tags' => $this->tags->implode(' ') ?? null, // 'tags' => $this->tags->implode(' ') ?? null,
// ]; // ];
// } // }
public function webUrl(){
return '#';// WIP
return route('');
}
} }

@ -188,5 +188,9 @@ class Product extends Model implements HasMedia
} }
public function webUrl(){
return '#';// WIP
return route('');
}
} }

@ -12,6 +12,10 @@ class Setting extends Model
public $translatable = ['value']; public $translatable = ['value'];
public static $settingTypes = ['TEXT', 'LONGTEXT', 'CODE', 'EDITOR', public static $settingTypes = ['TEXT','NUMBER', 'LONGTEXT', 'CODE', 'EDITOR',
'CATEGORY', 'GROUP', 'CHECKBOX', 'FILE', 'COLOR']; 'CATEGORY', 'GROUP', 'CHECKBOX', 'FILE', 'COLOR','SELECT'];
public function getData(){
return json_decode($this->data,true);
}
} }

@ -25,9 +25,11 @@ class PartObsever
// remove old part add new part // remove old part add new part
if ($part->isDirty('part')){ if ($part->isDirty('part')){
$className = ucfirst($part->getOriginal('part')); $p = clone $part;
$handle = "\\Resources\\Views\\Segments\\$className"; $p->part = $part->getOriginal('part');
$handle::onRemove($part); $classNameOld = ucfirst($part->getOriginal('part'));
$handleOld = "\\Resources\\Views\\Segments\\$classNameOld";
$handleOld::onRemove($p);
$className = $part->part; $className = $part->part;
$className= ucfirst($part->part); $className= ucfirst($part->part);
@ -37,6 +39,7 @@ class PartObsever
} }
/** /**
* Handle the Part "deleted" event. * Handle the Part "deleted" event.
*/ */

@ -22,6 +22,7 @@ return new class extends Migration
$table->boolean('ltr')->default(false); $table->boolean('ltr')->default(false);
$table->boolean('is_basic')->default(false); $table->boolean('is_basic')->default(false);
$table->boolean('size')->default('12'); $table->boolean('size')->default('12');
$table->json('data')->nullable();
$table->timestamps(); $table->timestamps();
}); });
} }

@ -18,7 +18,7 @@ class AreaSeeder extends Seeder
[ [
'name' => 'preloader', 'name' => 'preloader',
'valid_segments' => json_encode( 'valid_segments' => json_encode(
['preloader'] ["preloader"]
), ),
'max' => 1, 'max' => 1,
'icon' => 'ri-loader-2-line', 'icon' => 'ri-loader-2-line',
@ -26,7 +26,9 @@ class AreaSeeder extends Seeder
[ [
'name' => 'index', 'name' => 'index',
'valid_segments' => json_encode( 'valid_segments' => json_encode(
['top','slider','header','footer','menu','parallax'] ["top","slider","header","footer","menu",
"parallax","other","posts","products","attachments"
,"groups","categories"]
), ),
'max' => 10, 'max' => 10,
'icon' => 'ri-layout-top-2-line', 'icon' => 'ri-layout-top-2-line',

@ -2,4 +2,7 @@
// IF YOU WANT ADD ANY CODE CREATE NEW JS INTO client-custom // IF YOU WANT ADD ANY CODE CREATE NEW JS INTO client-custom
import "./client-custom/assetsNode.js"; import "./client-custom/assetsNode.js";
import "./client-custom/confirm.js"; import "./client-custom/confirm.js";
import "../views/segments/preloader/PreloaderImage/PreloaderImage.js"; import "../views/segments/preloader/PreloaderCircle/PreloaderCircle.js";
import "../views/segments/top/TopSimple/TopSimple.js";
import "../views/segments/slider/SliderSimple/SliderSimple.js";
import "../views/segments/posts/PostsIconSimple/PostsIconSimple.js";

@ -4,6 +4,7 @@
<i class="ri-subtract-line"></i> <i class="ri-subtract-line"></i>
</div> </div>
<input type="text" class="form-control" <input type="text" class="form-control"
:name="xname"
v-model="val" v-model="val"
@keyup.up="inc" @keyup.up="inc"
@keyup.down="dec"> @keyup.down="dec">
@ -40,6 +41,10 @@ export default {
type: Number, type: Number,
default: 100 default: 100
}, },
xname:{
type: String,
default: '',
}
}, },
mounted() { mounted() {
if (!isNaN(this.modelValue)) { if (!isNaN(this.modelValue)) {

@ -1,15 +1,26 @@
// PLEASE DO NOT EDIT THIS FILE, // PLEASE DO NOT EDIT THIS FILE,
// IF YOU WANT ADD ANY CODE CREATE NEW SCSS INTO client-custom // IF YOU WANT ADD ANY CODE CREATE NEW SCSS INTO client-custom
$xshop-background:#eeeeee;
$xshop-primary:#6e0000;
$xshop-diff:#ffffff;
$xshop-secondary:#ff0000;
$xshop-text:#111111;
$xshop-border-radius:7px;
$xshop-shadow:2px 2px 4px #777777;
:root{ :root{
--xshop-background:#eeeeee; --xshop-background:#eeeeee;
--xshop-primary:#6e0000; --xshop-primary:#6e0000;
--xshop-diff:#ffffff;
--xshop-secondary:#ff0000; --xshop-secondary:#ff0000;
--xshop-text:#111111; --xshop-text:#111111;
--border-radius:7px; --xshop-border-radius:7px;
--xshop-shadow:2px 2px 4px #777777; --xshop-shadow:2px 2px 4px #777777;
} }
@import "client-custom/assetsNode"; @import "client-custom/assetsNode";
@import "client-custom/general"; @import "client-custom/general";
@import "client-custom/zfix"; @import "client-custom/zfix";
@import "../views/segments/preloader/PreloaderImage/PreloaderImage"; @import "../views/segments/preloader/PreloaderCircle/PreloaderCircle";
@import "../views/segments/top/TopSimple/TopSimple";
@import "../views/segments/slider/SliderSimple/SliderSimple";
@import "../views/segments/posts/PostsIconSimple/PostsIconSimple";

@ -2,7 +2,7 @@
<label for="{{$setting->key}}"> <label for="{{$setting->key}}">
{{$setting->title}} {{$setting->title}}
{{-- // WIP translate--}} {{-- // WIP translate--}}
</label> </label>
@switch($setting->type) @switch($setting->type)
@ -33,7 +33,7 @@
@case('CATEGORY') @case('CATEGORY')
<searchable-select <searchable-select
@error('category_id') :err="true" @enderror @error('category_id') :err="true" @enderror
:items='@json($cats)' :items='@json($cats)'
title-field="name" title-field="name"
value-field="id" value-field="id"
xlang="{{config('app.locale')}}" xlang="{{config('app.locale')}}"
@ -46,7 +46,7 @@
@case('GROUP') @case('GROUP')
<searchable-select <searchable-select
@error('category_id') :err="true" @enderror @error('category_id') :err="true" @enderror
:items='@json($groups)' :items='@json($groups)'
title-field="name" title-field="name"
value-field="id" value-field="id"
xlang="{{config('app.locale')}}" xlang="{{config('app.locale')}}"
@ -62,6 +62,13 @@
name="{{$setting->key}}" class="form-control-color w-100" name="{{$setting->key}}" class="form-control-color w-100"
value="{{old($setting->key, $setting->value)}}" > value="{{old($setting->key, $setting->value)}}" >
@break @break
@case('NUMBER')
<br>
{{-- <input type="number" id="{{$setting->key}}"--}}
{{-- name="" class="form-control"--}}
{{-- value="" @if($setting->ltr) dir="ltr" @endif>--}}
<increment xname="{{$setting->key}}" xvalue="{{old($setting->key, $setting->value)}}" @foreach($setting->getData() as $k => $v) {{$k}}="{{$v}}" @endforeach ></increment>
@break
@case('FILE') @case('FILE')
<div class="row"> <div class="row">
@php($ext = strtolower(pathinfo(str_replace('_','.',$setting->key), PATHINFO_EXTENSION))) @php($ext = strtolower(pathinfo(str_replace('_','.',$setting->key), PATHINFO_EXTENSION)))
@ -99,9 +106,9 @@
@if (old($setting->key, $setting->value??'webp') == 'webp' ) selected @endif >{{__("webp")}} </option> @if (old($setting->key, $setting->value??'webp') == 'webp' ) selected @endif >{{__("webp")}} </option>
</select> </select>
@else @else
<input type="text" id="{{$setting->key}}" <input type="text" id="{{$setting->key}}"
name="{{$setting->key}}" class="form-control" name="{{$setting->key}}" class="form-control"
value="{{old($setting->key, $setting->value)}}" @if($setting->ltr) dir="ltr" @endif> value="{{old($setting->key, $setting->value)}}" @if($setting->ltr) dir="ltr" @endif>
@endif @endif
@endswitch @endswitch
</div> </div>

@ -0,0 +1,31 @@
<section class='PostsIconSimple py-4'>
<div class="{{gfx()['container']}}">
<h1>
<a href="{{getGroupBySetting($data->area->name.'_'.$data->part)->webUrl()}}">
{{getGroupBySetting($data->area->name.'_'.$data->part)->name}}
</a>
</h1>
<p>
{{getGroupBySetting($data->area->name.'_'.$data->part)->description}}
</p>
<div class="row">
@foreach(getGroupPostsBySetting($data->area->name.'_'.$data->part, getSetting($data->area->name.'_'.$data->part.'_limit')) as $post)
<div class="col-md-4">
<i class="{{$post->icon}}"></i>
<h3>
{{$post->title}}
</h3>
<p>
{{$post->subtitle}}
</p>
<a href="{{$post->webUrl()}}" class="btn btn-outline-primary w-100">
{{__("Read more")}}
</a>
</div>
@endforeach
</div>
</div>
</section>

@ -0,0 +1,10 @@
{
"name": "PostsIconSimple",
"version": "1.0",
"author": "xStack",
"email": "xshop@xstack.ir",
"license": "GPL-3.0-or-later",
"url": "https:\/\/xstack.ir",
"author_url": "https:\/\/4xmen.ir",
"packages": []
}

@ -0,0 +1,46 @@
<?php
namespace Resources\Views\Segments;
use App\Models\Group;
use App\Models\Part;
use App\Models\Setting;
class PostsIconSimple
{
public static function onAdd(Part $part = null)
{
$setting = new Setting();
$setting->section = 'theme';
$setting->key = $part->area->name . '_' . $part->part;
$setting->value = Group::first()->id;
$setting->type = 'GROUP';
$setting->size = 6;
$setting->title = $part->area->name . ' ' . $part->part;
$setting->save();
$setting = new Setting();
$setting->section = 'theme';
$setting->key = $part->area->name . '_' . $part->part.'_limit';
$setting->value = 3;
$setting->size = 6;
$setting->type = 'NUMBER';
$setting->data = json_encode(['xmin' => 2, 'xmax' => 12]);
$setting->title = $part->area->name . ' ' . $part->part. ' limit';
$setting->save();
}
public static function onRemove(Part $part = null)
{
// \Log::info(' --- onRemove rem --- '.$part->area->name . '_' . $part->part);
// dd(Setting::where('key',$part->area->name . '_' . $part->part)->get());
Setting::where('key',$part->area->name . '_' . $part->part)->first()?->delete();
Setting::where('key',$part->area->name . '_' . $part->part.'_limit')->first()?->delete();
}
public static function onMount(Part $part = null)
{
return $part;
}
}

@ -0,0 +1,20 @@
.PostsIconSimple {
// scss
h1{
a{
color: $xshop-text ;
}
}
.row{
text-align: center;
i{
font-size: 75px;
color: var(--xshop-primary);
}
p{
text-align: justify;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

@ -8,14 +8,12 @@ class PreloaderCircle
{ {
public static function onAdd(Part $part = null) public static function onAdd(Part $part = null)
{ {
\Log::info('added '.$part->part.' on '.$part->segment);
} }
public static function onRemove(Part $part = null) public static function onRemove(Part $part = null)
{ {
\Log::info('remove '.$part->part.' on '.$part->segment);
} }
public static function onMount(Part $part = null) public static function onMount(Part $part = null)
{ {
\Log::info('monted '.$part->part.' on '.$part->segment); return $part;
} }
} }

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

@ -10,7 +10,6 @@ class PreloaderImage
{ {
public static function onAdd(Part $part = null) public static function onAdd(Part $part = null)
{ {
\Log::info('added '.$part->part.' on '.$part->segment);
$setting = new Setting(); $setting = new Setting();
$setting->key = 'PreloaderImage_gif'; $setting->key = 'PreloaderImage_gif';
$setting->title = ''; $setting->title = '';
@ -21,12 +20,11 @@ class PreloaderImage
} }
public static function onRemove(Part $part = null) public static function onRemove(Part $part = null)
{ {
\Log::info('remove '.$part->part.' on '.$part->segment);
Setting::where('key','PreloaderImage_gif')->delete(); Setting::where('key','PreloaderImage_gif')->delete();
File::delete(public_path('upload/images/').'PreloaderImage.gif'); File::delete(public_path('upload/images/').'PreloaderImage.gif');
} }
public static function onMount(Part $part = null) public static function onMount(Part $part = null)
{ {
\Log::info('monted '.$part->part.' on '.$part->segment); return $part;
} }
} }

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

@ -16,6 +16,6 @@ class SliderSimple
} }
public static function onMount(Part $part = null) public static function onMount(Part $part = null)
{ {
return $part;
} }
} }

Before

Width:  |  Height:  |  Size: 463 KiB

After

Width:  |  Height:  |  Size: 463 KiB

@ -16,6 +16,6 @@ class TopSimple
} }
public static function onMount(Part $part = null) public static function onMount(Part $part = null)
{ {
return $part;
} }
} }

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@ -5,6 +5,7 @@
@endsection @endsection
@section('content') @section('content')
@foreach(getParts('index') as $part) @foreach(getParts('index') as $part)
@include($part->getBlade()) @php($p = $part->getBladeWithData())
@include($p['blade'],['data' => $p['data']])
@endforeach @endforeach
@endsection @endsection

Loading…
Cancel
Save