firstcommit

This commit is contained in:
2025-08-17 16:23:14 +05:45
commit 76bf4c0a18
2648 changed files with 362795 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
<?php
namespace Modules\Setting\Repositories;
interface SettingDao
{
public function findAll($limit = null, $filter = [], $sort = ['id', 'DESC']);
public function findOne($id);
public function create($data);
public function update($id, $data);
public function delete($id);
public function upload($file);
public function getLatest();
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Modules\Setting\Repositories;
use Modules\Setting\app\Models\Setting;
use Modules\FileManagement\Entities\FileManagement;
use Modules\FileManagement\Services\FileManagementService;
class SettingDaoImpl implements SettingDao
{
// protected $fileManagementService;
// public function __construct(FileManagementService $fileManagementService)
// {
// $this->fileManagementService = $fileManagementService;
// }
public function findAll($limit = null, $filter = [], $sort = ['id', 'DESC'])
{
$result = Setting::when(array_keys($filter, true), function ($query) use ($filter) {
if (isset($filter['client_id']) && !empty($filter['client_id'])) {
$query->where('client_id', $filter['client_id']);
}
})
->orderBy($sort[0], $sort[1])
->paginate($limit ? $limit : env('DEF_PAGE_LIMIT', 999));
return $result;
}
public function findOne($id)
{
return Setting::where('id', $id)->first();
}
public function create($data)
{
$model = Setting::create($data);
return $model;
}
public function update($id, $data)
{
// $model = Setting::find($id);
$model = Setting::with('files')->where('id', $id)->first();
$result = $model->update($data);
return $result;
}
public function delete($id)
{
$model = Setting::find($id);
$result = $model->delete();
return $result;
}
public function upload($file)
{
$fileExtension = $file->getSettingOriginalExtension();
$fileName = 'NRJ' . time() . '.' . $fileExtension;
$file->move(public_path() . '/' . Setting::FILE_PATH, $fileName);
return $fileName;
}
public function getLatest()
{
return Setting::orderBy('id', 'DESC')->first();
}
}

View File

@@ -0,0 +1,207 @@
<?php
namespace Modules\Setting\app\Http\Controllers;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Session;
use Modules\Setting\app\Models\Setting;
use Modules\Setting\app\Models\SettingImage;
use Modules\Setting\Repositories\SettingDaoImpl;
use Modules\Setting\app\Services\FileManagementService;
use Modules\Setting\app\Http\Requests\CreateSettingRequest;
use Modules\Setting\app\Http\Requests\UpdateSettingRequest;
use Modules\Setting\app\Http\Requests\CreateOrUpdateSettingRequest;
use Modules\Setting\app\Http\Requests\CreateOrUpdateSeoSettingRequest;
use Modules\Setting\app\Http\Requests\CreateOrUpdateGeneralSettingRequest;
use Modules\Setting\app\Http\Requests\CreateOrUpdateAdditionalSettingRequest;
use Modules\Setting\app\Http\Requests\CreateOrUpdateConnectionSettingRequest;
class SettingController extends Controller
{
//-- Get all the settings
public function index()
{
try {
$data['generalSettings'] = Setting::where('setting_name', 'general_setting')
->pluck('detail', 'name')
->all();
$data['settingImage'] = Setting::where('setting_name', 'setting_image')
->pluck('detail', 'name')
->all();
$data['socialShares'] = Setting::where('setting_name', 'social_setting')->get();
$data['seoSettings'] = Setting::where('setting_name', 'seo_setting')->pluck('detail', 'name')->all();
$data['additionalSettings'] = Setting::where('setting_name', 'additional_setting')->pluck('detail', 'name')->all();
return view('setting::create', $data);
} catch (\Throwable $th) {
throw $th;
report($th);
toastr()->error('Oops! Something went wrong.');
return back();
}
}
//-- Create or Update general setting
public function generalStoreOrUpdate(CreateOrUpdateGeneralSettingRequest $request)
{
try {
$validated = $request->validated();
// Check if general setting already exists
$generalSetting = Setting::where('setting_name', 'general_setting')->first();
if ($generalSetting) {
// Update existing general settings
foreach ($validated as $key => $generalSettingItem) {
$generalSettingContent = Setting::where('setting_name', 'general_setting')->where('name', $key)->first();
if ($generalSettingContent && !is_null($generalSettingContent)) {
// Check if the file exists in the request and matches the current $generalSettingItem
if ($request->hasFile($key)) {
FileManagementService::uploadFile(
file: $request->file($key),
uploadedFolderName: 'settings',
filePath: $generalSettingContent->detail,
model: $generalSettingContent
);
} else {
$generalSettingContent->detail = $generalSettingItem;
$generalSettingContent->save();
}
} else {
$newGeneralSetting = new Setting();
$newGeneralSetting->uuid = Str::uuid();
$newGeneralSetting->setting_name = 'general_setting';
$newGeneralSetting->name = $key;
if ($request->hasFile($key)) {
FileManagementService::storeFile(
file: $request->file($key),
uploadedFolderName: 'settings',
model: $newGeneralSetting
);
} else {
$newGeneralSetting->detail = $generalSettingItem;
$newGeneralSetting->save();
}
}
}
} else {
// Create new general settings data
foreach ($validated as $key => $generalSettingItem) {
$newGeneralSetting = new Setting();
$newGeneralSetting->uuid = Str::uuid();
$newGeneralSetting->setting_name = 'general_setting';
$newGeneralSetting->name = $key;
if ($request->hasFile($key)) {
FileManagementService::storeFile(
file: $request->file($key),
uploadedFolderName: 'settings',
model: $newGeneralSetting
);
} else {
$newGeneralSetting->detail = $generalSettingItem;
$newGeneralSetting->save();
}
}
}
$message = $generalSetting ? "General Setting updated successfully." : "General Setting created successfully.";
toastr()->success($message);
return redirect()->route('setting.index');
} catch (\Throwable $th) {
DB::rollback();
report($th);
toastr()->error('Something went wrong.');
return back();
}
}
//-- Create or Update connection setting
public function connectionStoreOrUpdate(Request $request)
{
try {
foreach ($request->socialShares as $socialshare) {
if (!empty($socialshare['social_site'])) {
Setting::updateOrCreate(
['name' => $socialshare['social_site']],
[
'uuid' => Str::uuid(),
'setting_name' => 'social_setting',
'name' => $socialshare['social_site'],
'detail' => $socialshare['social_link'],
]
);
}
}
toastr()->success('Connection Setting created successfully.');
return redirect()->route('setting.index');
} catch (\Throwable $th) {
DB::rollback();
report($th);
toastr()->error('Something went wrong.');
return back();
}
}
//-- Create or Update seo setting
public function seoStoreOrUpdate(CreateOrUpdateSeoSettingRequest $request)
{
try {
$validated = $request->validated();
foreach ($validated as $key => $seoSetting) {
Setting::updateOrCreate(
['name' => $key],
[
'uuid' => Str::uuid(),
'setting_name' => 'seo_setting',
'name' => $key,
'detail' => $seoSetting,
]
);
}
toastr()->success('SEO Setting created successfully.');
return redirect()->route('setting.index');
} catch (\Throwable $th) {
DB::rollback();
report($th);
toastr()->error('Something went wrong.');
return back();
}
}
public function additionalStoreOrUpdate(CreateOrUpdateAdditionalSettingRequest $request)
{
try {
$validated = $request->validated();
foreach ($validated as $key => $additonalSetting) {
Setting::updateOrCreate(
['name' => $key],
[
'uuid' => Str::uuid(),
'setting_name' => 'additional_setting',
'name' => $key,
'detail' => $additonalSetting,
]
);
}
toastr()->success('Additional Settings updated successfully.');
return redirect()->route('setting.index');
} catch (\Throwable $th) {
DB::rollback();
report($th);
toastr()->error('Something went wrong.');
return back();
}
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Modules\Setting\app\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateOrUpdateAdditionalSettingRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'additional_script' => 'nullable|string',
'map' => 'nullable|string',
];
}
public function messages()
{
return [
'additional_script.string' => 'The additional script field must be a string.',
'map.string' => 'The map field must be a string.',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Modules\Setting\app\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateOrUpdateConnectionSettingRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
//
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Modules\Setting\app\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
class CreateOrUpdateGeneralSettingRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'primary_image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:3072',
'secondary_image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:3072',
'company_name' => 'required|string|max:255',
'address' => 'nullable|string|max:255',
'contact_number' => 'nullable|string|max:255',
'info_email_address' => 'nullable|email|max:255',
'mobile_number' => 'nullable|string|max:255',
'alt_mobile_number' => 'nullable|string|max:255',
'support_email_address' => 'nullable|email|max:255',
'opening_hours' => 'nullable|string|max:255',
'short_detail' => 'nullable|string',
];
}
public function messages()
{
return [
'primary_image.image' => 'The primary image must be an image file.',
'primary_image.mimes' => 'The primary image must be a file of type: jpeg, png, jpg, gif.',
'primary_image.max' => 'The primary image may not be greater than 3MB.',
'secondary_image.image' => 'The secondary image must be an image file.',
'secondary_image.mimes' => 'The secondary image must be a file of type: jpeg, png, jpg, gif.',
'secondary_image.max' => 'The secondary image may not be greater than 3MB.',
'company_name.required' => 'The company name field is required.',
'company_name.string' => 'The company name field must be a string.',
'company_name.max' => 'The company name may not be greater than 255 characters.',
'address.string' => 'The address field must be a string.',
'address.max' => 'The address may not be greater than 255 characters.',
'contact_number.string' => 'The contact number field must be a string.',
'contact_number.max' => 'The contact number may not be greater than 255 characters.',
'info_email_address.email' => 'The info email address must be a valid email address.',
'info_email_address.max' => 'The info email address may not be greater than 255 characters.',
'mobile_number.string' => 'The mobile number field must be a string.',
'mobile_number.max' => 'The mobile number may not be greater than 255 characters.',
'alt_mobile_number.string' => 'The alt mobile number field must be a string.',
'alt_mobile_number.max' => 'The alt mobile number may not be greater than 255 characters.',
'support_email_address.email' => 'The support email address must be a valid email address.',
'support_email_address.max' => 'The support email address may not be greater than 255 characters.',
'opening_hours.string' => 'The opening hours field must be a string.',
'opening_hours.max' => 'The opening hours may not be greater than 255 characters.',
'short_detail.string' => 'The short detail field must be a string.',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Modules\Setting\app\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateOrUpdateSeoSettingRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'meta_keywords' => 'sometimes|nullable|string|max:255',
'meta_detail' => 'sometimes|nullable|string|max:255',
'meta_title' => 'sometimes|nullable|string|max:255',
];
}
public function messages()
{
return [
'meta_keywords.string' => 'The meta keywords field must be a string.',
'meta_keywords.max' => 'The meta keywords may not be greater than 255 characters.',
'meta_detail.string' => 'The meta detail field must be a string.',
'meta_detail.max' => 'The meta detail may not be greater than 255 characters.',
'meta_title.string' => 'The meta title field must be a string.',
'meta_title.max' => 'The meta title may not be greater than 255 characters.',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

View File

@@ -0,0 +1,34 @@
<?php
namespace Modules\Setting\app\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Setting\Database\factories\SettingFactory;
class Setting extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'uuid',
'setting_name',
'name',
'detail',
'status',
];
// protected static function newFactory(): SettingFactory
// {
// //return SettingFactory::new();
// }
/**
* Function to get full image path
*/
}

View File

View File

@@ -0,0 +1,59 @@
<?php
namespace Modules\Setting\app\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* The module namespace to assume when generating URLs to actions.
*/
protected string $moduleNamespace = 'Modules\Setting\app\Http\Controllers';
/**
* Called before routes are registered.
*
* Register any model bindings or pattern based filters.
*/
public function boot(): void
{
parent::boot();
}
/**
* Define the routes for the application.
*/
public function map(): void
{
$this->mapApiRoutes();
$this->mapWebRoutes();
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*/
protected function mapWebRoutes(): void
{
Route::middleware('web')
->namespace($this->moduleNamespace)
->group(module_path('Setting', '/routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*/
protected function mapApiRoutes(): void
{
Route::prefix('api')
->middleware('api')
->namespace($this->moduleNamespace)
->group(module_path('Setting', '/routes/api.php'));
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace Modules\Setting\app\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class SettingServiceProvider extends ServiceProvider
{
protected string $moduleName = 'Setting';
protected string $moduleNameLower = 'setting';
/**
* Boot the application events.
*/
public function boot(): void
{
$this->registerCommands();
$this->registerCommandSchedules();
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
$this->loadMigrationsFrom(module_path($this->moduleName, 'database/migrations'));
}
/**
* Register the service provider.
*/
public function register(): void
{
$this->app->register(RouteServiceProvider::class);
}
/**
* Register commands in the format of Command::class
*/
protected function registerCommands(): void
{
// $this->commands([]);
}
/**
* Register command Schedules.
*/
protected function registerCommandSchedules(): void
{
// $this->app->booted(function () {
// $schedule = $this->app->make(Schedule::class);
// $schedule->command('inspire')->hourly();
// });
}
/**
* Register translations.
*/
public function registerTranslations(): void
{
$langPath = resource_path('lang/modules/'.$this->moduleNameLower);
if (is_dir($langPath)) {
$this->loadTranslationsFrom($langPath, $this->moduleNameLower);
$this->loadJsonTranslationsFrom($langPath);
} else {
$this->loadTranslationsFrom(module_path($this->moduleName, 'lang'), $this->moduleNameLower);
$this->loadJsonTranslationsFrom(module_path($this->moduleName, 'lang'));
}
}
/**
* Register config.
*/
protected function registerConfig(): void
{
$this->publishes([module_path($this->moduleName, 'config/config.php') => config_path($this->moduleNameLower.'.php')], 'config');
$this->mergeConfigFrom(module_path($this->moduleName, 'config/config.php'), $this->moduleNameLower);
}
/**
* Register views.
*/
public function registerViews(): void
{
$viewPath = resource_path('views/modules/'.$this->moduleNameLower);
$sourcePath = module_path($this->moduleName, 'resources/views');
$this->publishes([$sourcePath => $viewPath], ['views', $this->moduleNameLower.'-module-views']);
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
$componentNamespace = str_replace('/', '\\', config('modules.namespace').'\\'.$this->moduleName.'\\'.config('modules.paths.generator.component-class.path'));
Blade::componentNamespace($componentNamespace, $this->moduleNameLower);
}
/**
* Get the services provided by the provider.
*/
public function provides(): array
{
return [];
}
private function getPublishableViewPaths(): array
{
$paths = [];
foreach (config('view.paths') as $path) {
if (is_dir($path.'/modules/'.$this->moduleNameLower)) {
$paths[] = $path.'/modules/'.$this->moduleNameLower;
}
}
return $paths;
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Modules\Setting\app\Services;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
class FileManagementService
{
//-- store file
public static function storeFile($file, $uploadedFolderName, $model)
{
try {
$originalFileName = $file->getClientOriginalName();
$modifiedFileName = date('YmdHis') . "_" . uniqid() . "." . $originalFileName;
$file->storeAs($uploadedFolderName, $modifiedFileName, 'public_uploads'); // This line uses 'public_uploads' disk
$model->detail = $uploadedFolderName . '/' . $modifiedFileName;
$model->save();
} catch (\Throwable $th) {
report($th);
toastr()->error('Something went wrong in image.');
return redirect()->back();
}
}
//-- update file
public static function uploadFile($file, $uploadedFolderName, $filePath, $model)
{
try {
if ($filePath && Storage::disk('public_uploads')->exists($filePath)) {
Storage::disk('public_uploads')->delete($filePath);
}
$originalFileName = $file->getClientOriginalName();
$modifiedFileName = date('YmdHis') . "_" . uniqid() . "." . $originalFileName;
$file->storeAs($uploadedFolderName, $modifiedFileName, 'public_uploads'); // This line uses 'public_uploads' disk
// $model->uuid = Str::uuid();
// $model->setting_name = 'setting_image';
// $model->name = $modifiedFileName;
$model->detail = $uploadedFolderName . '/' . $modifiedFileName;
$model->save();
} catch (\Throwable $th) {
report($th);
toastr()->error('Something went wrong.');
return redirect()->back();
}
}
//-- delete file
public static function deleteFile($filePath)
{
try {
if ($filePath && Storage::disk('public_uploads')->exists($filePath)) {
Storage::disk('public_uploads')->delete($filePath);
} else {
toastr()->error('File Not wrong.');
}
} catch (\Throwable $th) {
report($th);
toastr()->error('Something went wrong while deleting the file.');
}
}
}

View File

@@ -0,0 +1,31 @@
{
"name": "nwidart/setting",
"description": "",
"authors": [
{
"name": "Nicolas Widart",
"email": "n.widart@gmail.com"
}
],
"extra": {
"laravel": {
"providers": [],
"aliases": {
}
}
},
"autoload": {
"psr-4": {
"Modules\\Setting\\": "",
"Modules\\Setting\\App\\": "app/",
"Modules\\Setting\\Database\\Factories\\": "database/factories/",
"Modules\\Setting\\Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Modules\\Setting\\Tests\\": "tests/"
}
}
}

View File

View File

@@ -0,0 +1,5 @@
<?php
return [
'name' => 'Setting',
];

View File

@@ -0,0 +1,54 @@
<?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('settings', function (Blueprint $table) {
$table->id();
$table->uuid();
$table->string('setting_name');
$table->string('name')->nullable();
$table->text('detail')->nullable();
$table->string('status')->default('active');
$table->softDeletes();
// $table->string('company_name');
// $table->string('address')->nullable();
// $table->string('contact_number')->nullable();
// $table->string('email_info')->nullable();
// $table->string('mobile_number')->nullable();
// $table->string('mobile_number_2')->nullable();
// $table->string('email_support')->nullable();
// $table->string('opening_hours')->nullable();
// $table->string('support_email_address')->nullable();
// $table->date('establish_date')->nullable();
// $table->text('short_detail')->nullable();
// $table->string('meta_title')->nullable();
// $table->text('meta_detail')->nullable();
// $table->text('meta_keywords')->nullable();
// $table->string('facebook')->nullable();
// $table->string('twitter')->nullable();
// $table->string('instagram')->nullable();
// $table->string('youtube')->nullable();
// $table->text('additional_script', 1000)->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('settings');
}
};

View File

@@ -0,0 +1,85 @@
<?php
namespace Modules\Setting\database\seeders;
use Illuminate\Support\Str;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Storage;
use Modules\Setting\app\Models\Setting;
class SettingDatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$settings = [
//-- General setting
['setting_name' => 'general_setting', 'name' => 'company_name', 'detail' => 'Arogin'],
['setting_name' => 'general_setting', 'name' => 'address', 'detail' => 'Bhaktapur'],
['setting_name' => 'general_setting', 'name' => 'contact_number', 'detail' => '6600000'],
['setting_name' => 'general_setting', 'name' => 'mobile_number', 'detail' => '9800000000'],
['setting_name' => 'general_setting', 'name' => 'alt_mobile_number', 'detail' => '9700000000'],
['setting_name' => 'general_setting', 'name' => 'info_email_address', 'detail' => 'info@jhigucms.com'],
['setting_name' => 'general_setting', 'name' => 'support_email_address', 'detail' => 'support@jhigucms.com'],
['setting_name' => 'general_setting', 'name' => 'opening_hours', 'detail' => '6:00 AM - 10:00 PM'],
['setting_name' => 'general_setting', 'name' => 'short_detail', 'detail' => "At Arogin Company, we're dedicated to simplifying your online journey. Our user-friendly Content Management System (CMS) empowers you to create, customize, and manage stunning websites effortlessly. With responsive design, scalability, and top-notch security, we're here to help you succeed in the digital world."],
['setting_name' => 'setting_image', 'name' => 'primary_image', 'detail' => 'jhigutechwhite.png'],
['setting_name' => 'setting_image', 'name' => 'secondary_image', 'detail' => 'jhigutechBlack.png'],
//-- Social media share
['setting_name' => 'social_setting', 'name' => 'facebook', 'detail' => 'http://facebook.com'],
['setting_name' => 'social_setting', 'name' => 'instagram', 'detail' => 'http://twitter.com'],
['setting_name' => 'social_setting', 'name' => 'twitter', 'detail' => 'http://instagram.com'],
['setting_name' => 'social_setting', 'name' => 'google', 'detail' => 'http://pinterest.com'],
//-- Seo Settings
['setting_name' => 'seo_setting', 'name' => 'meta_title', 'detail' => 'Arogin'],
['setting_name' => 'seo_setting', 'name' => 'meta_detail', 'detail' => 'This is SEO section of JhiguCMS from where you can improve your Search optimization over internet.'],
['setting_name' => 'seo_setting', 'name' => 'meta_keywords', 'detail' => 'JhiguCMS, CMS, Jhigu, Content Management System, Legit Developers, CMS Platform'],
//-- Additional setting
['setting_name' => 'additional_setting', 'name' => 'additional_script', 'detail' => 'A Content Management System (CMS) is software that simplifies creating, managing, and modifying digital content without advanced technical skills. Key features include content creation, organization, user management, version control, SEO optimization, themes/templates, plugins/extensions, security, performance optimization, and analytics/reporting. Popular CMS options include WordPress, Joomla, Drupal, Magento, Wix, Squarespace, Ghost, and Umbraco. When choosing a CMS, consider scalability, ease of use, flexibility, and suitability for your specific website needs.'],
['setting_name' => 'additional_setting', 'name' => 'map', 'detail' => '<iframe width="100%" height="400" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?width=100%25&amp;height=400&amp;hl=en&amp;q=Bhaktapur%20Durbar%20Square+(Bhaktapur%20Durbar%20Square)&amp;t=p&amp;z=18&amp;ie=UTF8&amp;iwloc=B&amp;output=embed"><a href="https://www.maps.ie/population/">Calculate population in area</a></iframe>'],
];
foreach ($settings as $setting) {
Setting::create([
'uuid' => Str::uuid(),
'setting_name' => $setting['setting_name'],
'name' => $setting['name'],
'detail' => $setting['detail'],
]);
}
$setting_images = Setting::where('setting_name', 'setting_image')->orderBy('id', 'ASC')->get();
foreach ($setting_images as $setting_image) {
$this->uploadImageForSetting($setting_image->detail, $setting_image, $setting_image->name);
}
}
private function uploadImageForSetting(string $imageFileName, $setting, $settingImageFieldName)
{
$seederDirPath = 'settings/';
// Generate a unique filename for the new image
$newFileName = Str::uuid() . '.jpg';
// Storage path for the new image
$storagePath = 'settings/' . $newFileName;
// Check if the image exists in the seeder_disk
if (Storage::disk('seeder_disk')->exists($seederDirPath . $imageFileName)) {
// Copy the image from seeder to public
$fileContents = Storage::disk('seeder_disk')->get($seederDirPath . $imageFileName);
Storage::disk('public_uploads')->put($storagePath, $fileContents);
$setting->name = $settingImageFieldName;
$setting->detail = $storagePath;
$setting->save();
}
}
}

View File

View File

@@ -0,0 +1,11 @@
{
"name": "Setting",
"alias": "setting",
"description": "",
"keywords": [],
"priority": 0,
"providers": [
"Modules\\Setting\\app\\Providers\\SettingServiceProvider"
],
"files": []
}

View File

@@ -0,0 +1,15 @@
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.5",
"sass": "^1.69.5",
"postcss": "^8.3.7",
"vite": "^4.0.0"
}
}

View File

View File

@@ -0,0 +1,29 @@
@extends('admin::layouts.master')
@section('title')
Setting
@endsection
@section('breadcrumb')
@php
$breadcrumbData = [
[
'title' => 'Setting',
'link' => null,
],
[
'title' => 'General',
'link' => null,
],
];
@endphp
@include('admin::layouts.partials.breadcrumb', $breadcrumbData)
@endsection
@section('content')
<div class="content-wrapper container-xxl p-0">
<div class="content-body">
@include('setting::partial.form')
</div>
</div>
@endsection

View File

@@ -0,0 +1,13 @@
@extends('admin::layouts.master')
@section('title')
Setting
@endsection
@section('content')
<div class="content-wrapper container-xxl p-0">
<div class="content-body">
@include('setting::partial.form')
</div>
</div>
@endsection

View File

@@ -0,0 +1,9 @@
@extends('setting::layouts.master')
@section('content')
<h1>Hello World</h1>
<p>
This view is loaded from module: {!! config('setting.name') !!}
</p>
@endsection

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Setting Module - {{ config('app.name', 'Laravel') }}</title>
<meta name="description" content="{{ $description ?? '' }}">
<meta name="keywords" content="{{ $keywords ?? '' }}">
<meta name="author" content="{{ $author ?? '' }}">
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
{{-- Vite CSS --}}
{{-- {{ module_vite('build-setting', 'resources/assets/sass/app.scss') }} --}}
</head>
<body>
@yield('content')
{{-- Vite JS --}}
{{-- {{ module_vite('build-setting', 'resources/assets/js/app.js') }} --}}
</body>

View File

@@ -0,0 +1,46 @@
<div class="tab-pane fade show" id="pills-additional" role="tabpanel" aria-labelledby="pills-additional-tab">
<form action="{{ route('setting.additional.storeOrUpdate') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="card mb-4">
<h5 class="card-header">Additional Information</h5>
<hr class="my-0" />
<div class="card-body">
<div class="row">
<div class="mb-3 col-md-12">
<label class="form-label">Additional Script</label>
<textarea name="" id="mainTextarea" class="d-none"> {{ old('additional_script', $additionalSettings['additional_script'] ?? '') }}</textarea>
<textarea name="additional_script" rows="10" placeholder="Extra Script.." class="form-control full-editor"
id="editorTextarea"></textarea>
@error('additional_script')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-md-12">
<label class="form-label">Map Iframe</label>
<textarea name="map" rows="5" class="form-control mapInput">
{{ old('map', $additionalSettings['map'] ?? '') }}
</textarea>
@error('map')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mapContainer"></div>
</div>
<button type="submit" class="btn btn-primary me-2">Save Setting</button>
</div>
</div>
</form>
</div>
@push('required-styles')
@include('admin::vendor.full_editor.style')
@endpush
@push('required-scripts')
@include('admin::vendor.textareaContentDisplay.script')
@include('admin::vendor.full_editor.script')
@include('admin::vendor.mapDisplay.script')
@endpush

View File

@@ -0,0 +1,84 @@
<div class="tab-pane fade show" id="pills-connection" role="tabpanel" aria-labelledby="pills-connection-tab">
<form action="{{ route('setting.connection.storeOrUpdate') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="card mb-4">
<h5 class="card-header">Social Media Details</h5>
<!-- Connections -->
<hr class="my-0" />
<div class="card-body">
<div class="row">
<div class="repeater">
<div data-repeater-list="socialShares">
<div class="mb-1 d-flex justify-content-end">
<button class="btn btn-primary" data-repeater-create>
<i class="bx bx-plus me-1"></i>
<span class="align-middle">Add</span>
</button>
</div>
@foreach ($socialShares as $socialShare)
<div data-repeater-item>
<div class="row">
<div class="mb-3 col-lg-6 col-xl-3 col-4 mb-0">
<label class="form-label" for="{{ $socialShare->name }}">Name</label>
<input type="text" id="{{ $socialShare->name }}" class="form-control"
name="social_site" value="{{ old('name', $socialShare->name ?? '') }}"
placeholder="facebook" readonly />
@error('social_site')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-lg-6 col-xl-3 col-4 mb-0">
<label class="form-label" for="{{ $socialShare->detail }}">Link</label>
<input type="text" id="{{ $socialShare->detail }}" class="form-control"
name="social_link" value="{{ old('name', $socialShare->detail ?? '') }}"
placeholder="https://facebook.com/jhon-doe" />
@error('social_link')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-lg-12 col-xl-2 col-4 d-flex align-items-center mb-0">
<button class="btn btn-label-danger mt-4" data-repeater-delete>
<i class="bx bx-x me-1"></i>
<span class="align-middle">Delete</span>
</button>
</div>
</div>
<hr />
</div>
@endforeach
<div data-repeater-item>
<div class="row">
<div class="mb-3 col-lg-6 col-xl-3 col-4 mb-0">
<label class="form-label" for="">Name</label>
<input type="text" id="" class="form-control" name="social_site"
value="{{ old('name') }}" placeholder="facebook" />
</div>
<div class="mb-3 col-lg-6 col-xl-3 col-4 mb-0">
<label class="form-label" for="">Link</label>
<input type="text" id="" class="form-control" name="social_link"
value="{{ old('name') }}" placeholder="https://facebook.com/jhon-doe" />
</div>
<div class="mb-3 col-lg-12 col-xl-2 col-4 d-flex align-items-center mb-0">
<button class="btn btn-label-danger mt-4" data-repeater-delete>
<i class="bx bx-x me-1"></i>
<span class="align-middle">Delete</span>
</button>
</div>
</div>
<hr />
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary me-2">Save Setting</button>
</div>
</div>
</form>
</div>
@push('required-scripts')
@include('admin::vendor.repeater.script')
@endpush

View File

@@ -0,0 +1,37 @@
<div class="row">
<div class="col-md-12">
{{-- All Tabs --}}
<ul class="nav nav-pills flex-column flex-md-row mb-3" id="pills-tab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="pills-general-tab" data-bs-toggle="pill"
data-bs-target="#pills-general" type="button" role="tab" aria-controls="pills-general"
aria-selected="true"><i class="bx bx-user me-1"></i> General</button>
</li>
<li class="nav-item">
<button class="nav-link" id="pills-connection-tab" data-bs-toggle="pill"
data-bs-target="#pills-connection" type="button" role="tab" aria-controls="pills-connection"
aria-selected="true"><i class="bx bx-network-chart me-1"></i>
Connection</button>
</li>
<li class="nav-item">
<button class="nav-link" id="pills-seo-tab" data-bs-toggle="pill" data-bs-target="#pills-seo"
type="button" role="tab" aria-controls="pills-seo" aria-selected="true"><i
class="bx bx-world me-1"></i>
Seo</button>
</li>
<li class="nav-item">
<button class="nav-link" id="pills-additional-tab" data-bs-toggle="pill"
data-bs-target="#pills-additional" type="button" role="tab" aria-controls="pills-additional"
aria-selected="true"><i class="bx bx-copy-alt me-1"></i>
Additional</button>
</li>
</ul>
<div class="tab-content px-0" id="pills-tabContent">
{{-- Show related tabs data --}}
@include('setting::partial.general')
@include('setting::partial.connection')
@include('setting::partial.seo')
@include('setting::partial.additional')
</div>
</div>
</div>

View File

@@ -0,0 +1,166 @@
<div class="tab-pane fade show active" id="pills-general" role="tabpanel" aria-labelledby="pills-general-tab">
<form action="{{ route('setting.general.storeOrUpdate') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="card mb-4">
<h5 class="card-header">Basic Details</h5>
<div class="card-body">
<div class="row">
<div class="col-6 col-md-6 col-lg-6 d-flex align-items-start align-items-sm-center gap-4">
<img src="{{ asset(!empty($settingImage['primary_image']) ? 'storage/uploads/' . $settingImage['primary_image'] : 'backend/uploads/images/no-Image.jpg') }}"
alt="site-image input-file" class="d-block rounded show-image" height="100"
width="100" />
<div class="button-wrapper">
<label for="upload" class="btn btn-primary me-2 mb-4" tabindex="0">
<span class="d-none d-sm-block">Upload primary photo</span>
<i class="bx bx-upload d-block d-sm-none"></i>
<input type="file" id="upload" class="input-file" name="primary_image" hidden
accept="image/png, image/jpeg" />
</label>
<button type="button" class="btn btn-label-secondary image-reset mb-4">
<i class="bx bx-reset d-block d-sm-none"></i>
<span class="d-none d-sm-block">Reset</span>
</button>
<p class="mb-0">Allowed JPG, GIF or PNG. Max size of 3Mb</p>
</div>
</div>
<div class="col-6 col-md-6 col-lg-6 d-flex align-items-start align-items-sm-center gap-4">
<img src="{{ asset(!empty($settingImage['secondary_image']) ? 'storage/uploads/' . $settingImage['secondary_image'] : 'backend/uploads/images/no-Image.jpg') }}"
alt="site-image input-file" class="d-block rounded show-secondary" height="100"
width="100" />
<div class="button-wrapper">
<label for="uploadSecondary" class="btn btn-primary me-2 mb-4" tabindex="0">
<span class="d-none d-sm-block">Upload secondary photo</span>
<i class="bx bx-upload d-block d-sm-none"></i>
<input type="file" id="uploadSecondary" class="input-secondary"
name="secondary_image" hidden accept="image/png, image/jpeg" />
</label>
<button type="button" class="btn btn-label-secondary secondary-reset mb-4">
<i class="bx bx-reset d-block d-sm-none"></i>
<span class="d-none d-sm-block">Reset</span>
</button>
<p class="mb-0">Allowed JPG, GIF or PNG. Max size of 3Mb</p>
</div>
</div>
</div>
</div>
<hr class="my-0" />
<!-- Account -->
<div class="card-body">
<div class="row">
<div class="mb-3 col-md-6">
<label class="form-label">Name<span class="text-danger"> *</span></label>
<input type="text" name="company_name"
value="{{ old('company_name', isset($generalSettings['company_name']) ? $generalSettings['company_name'] : '') }}"
placeholder="e.g. Jhigu Technologies" class="form-control" required>
@error('company_name')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-md-6">
<label class="form-label">Address</label>
<input type="text" name="address"
value="{{ old('address', isset($generalSettings['address']) ? $generalSettings['address'] : '') }}"
placeholder="e.g. Bhaktapur, Bagmati, Nepal" class="form-control">
@error('address')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-md-6">
<label class="form-label">Contact Number</label>
<div class="input-group input-group-merge">
<span class="input-group-text">NP (+977)</span>
<input type="text" name="contact_number"
value="{{ old('contact_number', isset($generalSettings['contact_number']) ? $generalSettings['contact_number'] : '') }}"
placeholder="e.g. 9876543210" class="form-control">
@error('contact_number')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
</div>
<div class="mb-3 col-md-6">
<label class="form-label">E-mail (Info)</label>
<input type="text" name="info_email_address"
value="{{ old('info_email_address', isset($generalSettings['info_email_address']) ? $generalSettings['info_email_address'] : '') }}"
placeholder="e.g. info@jhigutech.com" class="form-control">
@error('info_email_address')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-md-6">
<label class="form-label">Mobile Number</label>
<div class="input-group input-group-merge">
<span class="input-group-text">NP (+977)</span>
<input type="text" name="mobile_number"
value="{{ old('mobile_number', isset($generalSettings['mobile_number']) ? $generalSettings['mobile_number'] : '') }}"
placeholder="e.g. 9876543210" class="form-control">
@error('mobile_number')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
</div>
<div class="mb-3 col-md-6">
<label class="form-label">Mobile Number (Alternative)</label>
<div class="input-group input-group-merge">
<span class="input-group-text">NP (+977)</span>
<input type="text" name="alt_mobile_number"
value="{{ old('alt_mobile_number', isset($generalSettings['alt_mobile_number']) ? $generalSettings['alt_mobile_number'] : '') }}"
placeholder="e.g. 9876543210" class="form-control">
@error('alt_mobile_number')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
</div>
<div class="mb-3 col-md-6">
<label class="form-label">E-mail (Support)</label>
<input type="text" name="support_email_address"
value="{{ old('support_email_address', isset($generalSettings['support_email_address']) ? $generalSettings['support_email_address'] : '') }}"
placeholder="e.g. support@jhigutech.com" class="form-control">
@error('support_email_address')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-md-6">
<label class="form-label">Opening Hours</label>
<input type="text" name="opening_hours"
value="{{ old('opening_hours', isset($generalSettings['opening_hours']) ? $generalSettings['opening_hours'] : '') }}"
placeholder="e.g. 9:00 AM - 10:00 PM" class="form-control">
@error('opening_hours')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-md-12">
<label class="form-label">Short Description</label>
<textarea name="" id="mainTextarea" class="d-none">{{ old('short_detail', isset($generalSettings['short_detail']) ? $generalSettings['short_detail'] : '') }}</textarea>
<textarea name="short_detail" rows="5" placeholder="Write short description" class="form-control full-editor"
id="editorTextarea"></textarea>
@error('short_detail')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
</div>
<div class="mt-2">
<button type="submit" class="btn btn-primary me-2">Save Setting</button>
</div>
</div>
</div>
</form>
</div>
@push('required-styles')
@include('admin::vendor.full_editor.style')
@endpush
@push('required-scripts')
@include('admin::vendor.textareaContentDisplay.script')
@include('admin::vendor.full_editor.script')
@endpush

View File

@@ -0,0 +1,52 @@
<div class="tab-pane fade show" id="pills-seo" role="tabpanel" aria-labelledby="pills-seo-tab">
<form action="{{ route('setting.seo.storeOrUpdate') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="card mb-4">
<h5 class="card-header">Meta Details</h5>
<!-- seo -->
<hr class="my-0" />
<div class="card-body">
<div class="row">
<div class="mb-3 col-md-12">
<label class="form-label">Title</label>
<input type="text" name="meta_title"
value="{{ old('meta_title', $seoSettings['meta_title'] ?? '') }}"
placeholder="e.g. Jhigu CMS Company - Empowering Your Web Presence" class="form-control">
@error('meta_title')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-md-12">
<label class="form-label">Description</label>
<textarea name="" id="mainTextarea" class="d-none">{{ old('meta_detail', $seoSettings['meta_detail'] ?? '') }}</textarea>
<textarea name="meta_detail" rows="5" class="form-control full-editor" id="editorTextarea"
placeholder="Jhigu CMS Company is a leading provider of user-friendly Content Management Systems (CMS) that empower businesses to create and manage dynamic websites effortlessly. Our customizable CMS, responsive design, and dedicated support make us the go-to choice for web development and content management solutions. Join us to simplify your online journey and achieve digital success with ease."></textarea>
@error('meta_detail')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3 col-md-12">
<label class="form-label">Keywords</label>
<textarea name="meta_keywords" rows="4" class="form-control"
placeholder="Jhigu CMS Company, Content Management System, CMS solutions, web development, responsive design, digital success">{{ old('meta_keywords', $seoSettings['meta_keywords'] ?? '') }}</textarea>
@error('meta_keywords')
<div class="text-danger">{{ $message }}</div>
@enderror
</div>
</div>
<button type="submit" class="btn btn-primary me-2">Save Setting</button>
</div>
</div>
</form>
</div>
@push('required-styles')
@include('admin::vendor.full_editor.style')
@endpush
@push('required-scripts')
@include('admin::vendor.textareaContentDisplay.script')
@include('admin::vendor.full_editor.script')
@endpush

View File

View File

@@ -0,0 +1,19 @@
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware(['auth:sanctum'])->prefix('v1')->name('api.')->group(function () {
Route::get('setting', fn (Request $request) => $request->user())->name('setting');
});

View File

@@ -0,0 +1,23 @@
<?php
use Illuminate\Support\Facades\Route;
use Modules\Setting\app\Http\Controllers\SettingController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::group(['prefix' => 'apanel', 'middleware' => []], function () {
Route::get('setting/', [SettingController::class, 'index'])->name('setting.index');
Route::post('setting/generalStoreOrUpdate', [SettingController::class, 'generalStoreOrUpdate'])->name('setting.general.storeOrUpdate');
Route::post('setting/connectionStoreOrUpdate', [SettingController::class, 'connectionStoreOrUpdate'])->name('setting.connection.storeOrUpdate');
Route::post('setting/seoStoreOrUpdate', [SettingController::class, 'seoStoreOrUpdate'])->name('setting.seo.storeOrUpdate');
Route::post('setting/additionalStoreOrUpdate', [SettingController::class, 'additionalStoreOrUpdate'])->name('setting.additional.storeOrUpdate');
});

View File

View File

View File

@@ -0,0 +1,26 @@
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
build: {
outDir: '../../public/build-setting',
emptyOutDir: true,
manifest: true,
},
plugins: [
laravel({
publicDirectory: '../../public',
buildDirectory: 'build-setting',
input: [
__dirname + '/resources/assets/sass/app.scss',
__dirname + '/resources/assets/js/app.js'
],
refresh: true,
}),
],
});
//export const paths = [
// 'Modules/$STUDLY_NAME$/resources/assets/sass/app.scss',
// 'Modules/$STUDLY_NAME$/resources/assets/js/app.js',
//];