optimized client command

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

@ -29,16 +29,22 @@ class clientAssetGenerator extends Command
{
// make gfx variable
$gfxes = gfx();
$vars['xshop-background'] = $gfxes['background'] ?? '#000000';
$vars['xshop-primary'] = $gfxes['primary'] ?? '#6e0000';
$vars['xshop-diff'] = getGrayscaleTextColor($gfxes['primary']) ?? '#6e0000';
$vars['xshop-secondary'] = $gfxes['secondary'] ?? '#ff0000';
$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';
// 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;
$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;
foreach ($vars as $k => $var) {
$variables .= "--$k:$var;" . PHP_EOL;

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

@ -2,6 +2,7 @@
use App\Helpers;
use App\Models\Setting;
use App\Models\Group;
use App\Models\Area;
use App\Models\Part;
use Illuminate\Support\Facades\Route;
@ -684,17 +685,18 @@ function nestedWithData($items, $parent_id = null)
* @param $areaName
* @return \App\Models\Part|false
*/
function hasPart($areaName){
$a = Area::where('name',$areaName)->first();
if ($a == null){
function hasPart($areaName)
{
$a = Area::where('name', $areaName)->first();
if ($a == null) {
return false;
}
$p = Part::where('area_id',$a->id)->first();
if ($p == null){
return false;
$p = Part::where('area_id', $a->id)->first();
if ($p == null) {
return false;
}
return $p ;
return $p;
}
@ -704,8 +706,9 @@ function hasPart($areaName){
* @param $areaName
* @return Part[]|\Illuminate\Database\Eloquent\Collection|\LaravelIdea\Helper\App\Models\_IH_Part_C
*/
function getParts($areaName){
$a = Area::where('name',$areaName)->first();
function getParts($areaName)
{
$a = Area::where('name', $areaName)->first();
return $a->parts()->orderBy('sort')->get();
}
@ -715,14 +718,61 @@ function getParts($areaName){
* @param $group
* @return array
*/
function getSettingsGroup($group){
function getSettingsGroup($group)
{
$result = [];
foreach (Setting::where('key','LIKE',$group.'%')
->whereNotNull('value')->get(['key','value']) as $r){
if ($r->value != null){
$result[substr($r->key,mb_strlen($group))] = $r->value;
foreach (Setting::where('key', 'LIKE', $group . '%')
->whereNotNull('value')->get(['key', 'value']) as $r) {
if ($r->value != null) {
$result[substr($r->key, mb_strlen($group))] = $r->value;
}
}
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',
'attachment',
'attachments',
'attachmentsList',
'attachments_page',
'card',
'categories',
'categories_page',
'category',
'clip',
'clips',
@ -26,14 +28,20 @@ class Area extends Model
'gallery',
'group',
'groups',
'groups_page',
'index',
'invoice',
'login',
'menu',
'other',
'parallax',
'post',
'posts',
'posts_page',
'preloader',
'product',
'products',
'products_page',
'questions',
'search',
'slider',

@ -70,4 +70,9 @@ class Category extends Model
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');
}
public function webUrl(){
return '#';// WIP
return route('');
}
}

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

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

@ -16,4 +16,13 @@ class Part extends Model
$handle::onMount($this);
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,
// ];
// }
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 static $settingTypes = ['TEXT', 'LONGTEXT', 'CODE', 'EDITOR',
'CATEGORY', 'GROUP', 'CHECKBOX', 'FILE', 'COLOR'];
public static $settingTypes = ['TEXT','NUMBER', 'LONGTEXT', 'CODE', 'EDITOR',
'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
if ($part->isDirty('part')){
$className = ucfirst($part->getOriginal('part'));
$handle = "\\Resources\\Views\\Segments\\$className";
$handle::onRemove($part);
$p = clone $part;
$p->part = $part->getOriginal('part');
$classNameOld = ucfirst($part->getOriginal('part'));
$handleOld = "\\Resources\\Views\\Segments\\$classNameOld";
$handleOld::onRemove($p);
$className = $part->part;
$className= ucfirst($part->part);
@ -37,6 +39,7 @@ class PartObsever
}
/**
* Handle the Part "deleted" event.
*/

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

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

@ -2,4 +2,7 @@
// IF YOU WANT ADD ANY CODE CREATE NEW JS INTO client-custom
import "./client-custom/assetsNode.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>
</div>
<input type="text" class="form-control"
:name="xname"
v-model="val"
@keyup.up="inc"
@keyup.down="dec">
@ -40,6 +41,10 @@ export default {
type: Number,
default: 100
},
xname:{
type: String,
default: '',
}
},
mounted() {
if (!isNaN(this.modelValue)) {

@ -1,15 +1,26 @@
// PLEASE DO NOT EDIT THIS FILE,
// 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{
--xshop-background:#eeeeee;
--xshop-primary:#6e0000;
--xshop-diff:#ffffff;
--xshop-secondary:#ff0000;
--xshop-text:#111111;
--border-radius:7px;
--xshop-border-radius:7px;
--xshop-shadow:2px 2px 4px #777777;
}
@import "client-custom/assetsNode";
@import "client-custom/general";
@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}}">
{{$setting->title}}
{{-- // WIP translate--}}
{{-- // WIP translate--}}
</label>
@switch($setting->type)
@ -33,7 +33,7 @@
@case('CATEGORY')
<searchable-select
@error('category_id') :err="true" @enderror
:items='@json($cats)'
:items='@json($cats)'
title-field="name"
value-field="id"
xlang="{{config('app.locale')}}"
@ -46,7 +46,7 @@
@case('GROUP')
<searchable-select
@error('category_id') :err="true" @enderror
:items='@json($groups)'
:items='@json($groups)'
title-field="name"
value-field="id"
xlang="{{config('app.locale')}}"
@ -62,6 +62,13 @@
name="{{$setting->key}}" class="form-control-color w-100"
value="{{old($setting->key, $setting->value)}}" >
@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')
<div class="row">
@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>
</select>
@else
<input type="text" id="{{$setting->key}}"
name="{{$setting->key}}" class="form-control"
value="{{old($setting->key, $setting->value)}}" @if($setting->ltr) dir="ltr" @endif>
<input type="text" id="{{$setting->key}}"
name="{{$setting->key}}" class="form-control"
value="{{old($setting->key, $setting->value)}}" @if($setting->ltr) dir="ltr" @endif>
@endif
@endswitch
</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)
{
\Log::info('added '.$part->part.' on '.$part->segment);
}
public static function onRemove(Part $part = null)
{
\Log::info('remove '.$part->part.' on '.$part->segment);
}
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)
{
\Log::info('added '.$part->part.' on '.$part->segment);
$setting = new Setting();
$setting->key = 'PreloaderImage_gif';
$setting->title = '';
@ -21,12 +20,11 @@ class PreloaderImage
}
public static function onRemove(Part $part = null)
{
\Log::info('remove '.$part->part.' on '.$part->segment);
Setting::where('key','PreloaderImage_gif')->delete();
File::delete(public_path('upload/images/').'PreloaderImage.gif');
}
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)
{
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)
{
return $part;
}
}

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

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

Loading…
Cancel
Save