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,132 @@
<?php
namespace Modules\Page\app\Http\Controllers;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Modules\Page\app\Models\Page;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Modules\Page\app\Models\PageMeta;
use Modules\Page\app\Repositories\PageRepository;
use Modules\Page\app\Services\FileManagementService;
use Modules\Page\app\Http\Requests\CreatePageRequest;
use Modules\Page\app\Http\Requests\UpdatePageRequest;
class PageController extends Controller
{
protected $pageRepository;
public function __construct()
{
$this->pageRepository = new PageRepository;
}
/**
* Display a listing of the resource.
*/
public function index()
{
$pages = $this->pageRepository->allPages();
return view('page::index', compact('pages'));
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('page::create');
}
/**
* Store a newly created resource in storage.
*/
public function store(CreatePageRequest $request): RedirectResponse
{
try {
$validated = $request->validated();
$this->pageRepository->storePage($validated);
toastr()->success('Page created successfully.');
return redirect()->route('cms.pages.index');
} catch (\Throwable $th) {
report($th);
toastr()->error('Something went wrong.');
return back();
}
}
/**
* Show the specified resource.
*/
public function show($id)
{
return view('page::show');
}
/**
* Show the form for editing the specified resource.
*/
public function edit($uuid)
{
$page = $this->pageRepository->findPageByUuid($uuid);
if (! $page) {
toastr()->error('Page not found.');
return back();
}
return view('page::edit', compact('page'));
}
/**
* Update the specified resource in storage.
*/
public function update(UpdatePageRequest $request, $uuid): RedirectResponse
{
try {
$validated = $request->validated();
$page = $this->pageRepository->updatePage($validated, $uuid);
if (! $page) {
toastr()->error('Page not found !');
return back();
}
toastr()->success('Page updated successfully.');
return redirect()->route('cms.pages.index');
} catch (\Throwable $th) {
report($th);
toastr()->error('Something went wrong.');
return back();
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy($uuid)
{
try {
$page = $this->pageRepository->deletePage($uuid);
if (! $page) {
toastr()->error('Page not found.');
return back();
}
DB::commit();
toastr()->success('Page deleted successfully.');
return redirect()->route('cms.pages.index');
} catch (\Throwable $th) {
DB::rollback();
report($th);
toastr()->error('Something went wrong.');
return back();
}
}
}

View File

View File

@@ -0,0 +1,36 @@
<?php
namespace Modules\Page\app\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreatePageRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:255',
'slug' => 'required|string|unique:pages,slug|max:255',
'summary' => 'required|string',
'description' => 'sometimes|nullable|string',
'display_order' => 'sometimes|nullable|integer',
'status' => 'required|in:active,inactive',
'image' => 'sometimes|nullable|image|mimes:jpeg,png,jpg,gif|max:2048', // Adjust the image rules as needed
'meta_title' => 'sometimes|nullable|string|max:255',
'meta_description' => 'sometimes|nullable|string|max:255',
'meta_keywords' => 'sometimes|nullable|string|max:255',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
// return auth()->user()->can('users.create');
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Modules\Page\app\Http\Requests;
use Modules\Page\app\Models\Page;
use Illuminate\Foundation\Http\FormRequest;
class UpdatePageRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:255',
'slug' => 'sometimes|required|string|max:255|unique:pages,slug,' . Page::where('uuid', request('uuid'))->first()->id,
// Exclude the current page by ID
'summary' => 'sometimes|nullable|string',
'description' => 'sometimes|nullable|string',
'display_order' => 'sometimes|nullable|integer',
'code' => 'sometimes|nullable|string',
'status' => 'sometimes|required|in:active,inactive',
'image' => 'sometimes|nullable|image|mimes:jpeg,png,jpg,gif|max:2048', // Adjust the image rules as needed
'meta_title' => 'sometimes|nullable|string|max:255',
'meta_description' => 'sometimes|nullable|string|max:255',
'meta_keywords' => 'sometimes|nullable|string|max:255',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
// return auth()->user()->can('users.create');
}
public function messages()
{
return [
'slug.unique' => 'The slug is already in use by another page.',
// Add custom error messages for other rules as needed
];
}
}

View File

View File

@@ -0,0 +1,55 @@
<?php
namespace Modules\Page\app\Models;
use Modules\Post\app\Models\Post;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Page extends Model
{
// use HasFactory;
use SoftDeletes;
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'title',
'slug',
'summary',
'description',
'display_order',
'code',
'status',
'image',
'image_path',
];
public function pageMeta()
{
return $this->hasOne(PageMeta::class, 'page_id');
}
/**
*
*/
public function posts()
{
return $this->hasMany(Post::class);
}
/**
*
*/
public function getFullImageAttribute()
{
$result = null;
if($this->image_path) {
$result = asset('storage/uploads/' . $this->image_path);
}
return $result;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Modules\Page\app\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Page\Database\factories\PageMetaFactory;
class PageMeta extends Model
{
// use HasFactory;
use SoftDeletes;
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'page_id',
'meta_title',
'meta_description',
'meta_keywords',
];
public function page()
{
return $this->belongsTo(Page::class, 'page_id');
}
protected static function newFactory(): PageMetaFactory
{
//return PageMetaFactory::new();
}
}

View File

View File

@@ -0,0 +1,114 @@
<?php
namespace Modules\Page\app\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class PageServiceProvider extends ServiceProvider
{
protected string $moduleName = 'Page';
protected string $moduleNameLower = 'page';
/**
* 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,59 @@
<?php
namespace Modules\Page\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\Page\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('Page', '/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('Page', '/routes/api.php'));
}
}

View File

@@ -0,0 +1,138 @@
<?php
namespace Modules\Page\app\Repositories;
use Illuminate\Support\Str;
use Modules\Page\app\Models\Page;
use Illuminate\Support\Facades\DB;
use Modules\Page\app\Models\PageMeta;
use Modules\Page\app\Services\FileManagementService;
class PageRepository
{
public function allPages($perPage = null, $filter = [], $sort = ['by' => 'id', 'sort' => 'ASC'])
{
return Page::with('pageMeta')->when(array_keys($filter, true), function ($query) use ($filter) {
})
->orderBy($sort['by'], $sort['sort'])
->paginate($perPage ?: env('PAGE_LIMIT', 999));
}
public function findPageByUuid($uuid)
{
return Page::where('uuid', $uuid)->first();
}
public function storePage(array $validated)
{
DB::beginTransaction();
try {
$page = new Page();
$page->uuid = Str::uuid();
$page->title = $validated['title'];
$page->slug = Str::slug($validated['slug']);
$page->summary = $validated['summary'];
$page->description = $validated['description'];
$page->display_order = $validated['display_order'];
$page->status = $validated['status'];
$page->code = 'normal';
$page->save();
if (isset($validated['image']) && $validated['image']->isValid()) {
FileManagementService::storeFile(
file: $validated['image'],
uploadedFolderName: 'pages',
model: $page
);
}
$pageMeta = new PageMeta();
$pageMeta->uuid = Str::uuid();
$pageMeta->meta_title = $validated['meta_title'];
$pageMeta->meta_description = $validated['meta_description'];
$pageMeta->meta_keywords = $validated['meta_keywords'];
$page->pageMeta()->save($pageMeta);
DB::commit();
return $page;
} catch (\Throwable $th) {
report($th);
DB::rollback();
return null;
}
}
public function updatePage($validated, $uuid)
{
DB::beginTransaction();
try {
$page = $this->findPageByUuid($uuid);
if (!$page) {
return null;
}
//-- Update page
$page->title = $validated['title'];
$page->slug = Str::slug($validated['slug']);
$page->summary = $validated['summary'];
$page->description = $validated['description'];
$page->display_order = $validated['display_order'];
$page->status = $validated['status'];
$page->save();
if (isset($validated['image']) && $validated['image']->isValid()) {
FileManagementService::uploadFile(
file: $validated['image'],
uploadedFolderName: 'pages',
filePath: $page->image_path,
model: $page
);
}
//-- Create or update page meta
$pageMeta = $page->pageMeta()->firstOrNew([]);
if (!$pageMeta->exists) {
$pageMeta->uuid = Str::uuid();
}
$pageMeta->meta_title = $validated['meta_title'];
$pageMeta->meta_description = $validated['meta_description'];
$pageMeta->meta_keywords = $validated['meta_keywords'];
$pageMeta->save();
DB::commit();
return $page;
} catch (\Throwable $th) {
report($th);
DB::rollBack();
return null;
}
}
public function deletePage(string $uuid)
{
DB::beginTransaction();
try {
$page = $this->findPageByUuid($uuid);
if (!$page) {
return null;
}
if ($page->image_path !== null) {
FileManagementService::deleteFile($page->image_path);
}
$page->pageMeta()->delete();
$page->delete();
DB::commit();
return $page;
} catch (\Throwable $th) {
DB::rollBack();
report($th);
return null;
}
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace Modules\Page\app\Services;
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->image = $modifiedFileName;
$model->image_path = $uploadedFolderName . '/' . $modifiedFileName;
$model->save();
} catch (\Throwable $th) {
report($th);
toastr()->error('Something went wrong.');
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->image = $modifiedFileName;
$model->image_path = $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/page",
"description": "",
"authors": [
{
"name": "Nicolas Widart",
"email": "n.widart@gmail.com"
}
],
"extra": {
"laravel": {
"providers": [],
"aliases": {
}
}
},
"autoload": {
"psr-4": {
"Modules\\Page\\": "",
"Modules\\Page\\App\\": "app/",
"Modules\\Page\\Database\\Factories\\": "database/factories/",
"Modules\\Page\\Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Modules\\Page\\Tests\\": "tests/"
}
}
}

View File

View File

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

View File

View File

@@ -0,0 +1,38 @@
<?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('pages', function (Blueprint $table) {
$table->id();
$table->uuid();
$table->string('title');
$table->string('slug')->unique();
$table->text('summary')->nullable();
$table->text('description')->nullable();
$table->integer('display_order')->nullable();
$table->string('code');
$table->string('image')->nullable();
$table->string('image_path')->nullable();
$table->string('status')->default('active');
$table->softDeletes();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('pages');
}
};

View File

@@ -0,0 +1,36 @@
<?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('page_metas', function (Blueprint $table) {
$table->id();
$table->uuid();
$table->unsignedBigInteger('page_id');
$table->string('meta_title')->nullable();
$table->longText('meta_description')->nullable();
$table->longText('meta_keywords')->nullable();
$table->softDeletes();
$table->timestamps();
$table->foreign('page_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('page_metas');
}
};

View File

View File

@@ -0,0 +1,194 @@
<?php
namespace Modules\Page\database\seeders;
use Illuminate\Support\Str;
use Illuminate\Database\Seeder;
use Modules\Page\app\Models\Page;
use Illuminate\Support\Facades\Storage;
class PageDatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$this->forHomePage();
$this->forAboutUsPage();
$this->forHairTransplantPage();
$this->forServicePage();
$this->forTeamMemberPage();
$this->forBlogPage();
}
/**************************** Seeders For Home Page **********************************/
private function forHomePage()
{
$homePage = Page::create([
'uuid' => Str::uuid(),
'title' => 'BEST TECHNOLOGY FOR HAIR TRANSPLANT',
'slug' => 'homepage',
'summary' => '',
'description' => '',
'code' => 'homepage',
'display_order' => 1,
]);
$homePage->pageMeta()->create([
'uuid' => Str::uuid(),
'meta_title' => 'Title for Home Page',
'meta_description' => 'Meta Description for Home Page',
'meta_keywords' => 'keyword1, keyword2, keyword3',
]);
}
/**************************** Seeders For AboutUs Page **********************************/
private function forAboutUsPage()
{
$aboutUsPage = Page::create([
'uuid' => Str::uuid(),
'title' => 'Arogin Health Care',
'slug' => 'about-us',
'summary' => 'Arogin Health Care & Research Centre (P) Ltd is a team of highly qualified medical professionals supported by experienced entrepreneurs. No hesitation, we call ourselves as Present & Future of quality medical services. Our consultants follow the standard evidence based guidelines as almost all of them are graduates from reputed medical institutes.',
'description' => 'Yes, we are here to serve you the best & fulfill a dream of healthy nation. Our tropical medicine expert Dr. Sanjay Acharya says “there are numerous measures of prevention but due to negligence and lack of awareness, we still suffer from diseases which would have not occurred with few simple measures." We, the team Arogin, with our key mantra “Patient care comes first”, dream not just being a top ranked health care hub but also fulfill the dream of healthy nation where people can trust their own domestic service providers.',
'code' => 'about_us',
'display_order' => 2,
]);
//-- Add Image
$this->uploadImageForPage('p4.jpg', $aboutUsPage);
$aboutUsPage->pageMeta()->create([
'uuid' => Str::uuid(),
'meta_title' => 'Title for About Page',
'meta_description' => 'Meta Description for About Page',
'meta_keywords' => 'keyword1, keyword2, keyword3',
]);
}
/**************************** Seeders For Hair Transplant Page **********************************/
private function forHairTransplantPage()
{
$servicePage = Page::create([
'uuid' => Str::uuid(),
'title' => 'Hair Transplant',
'slug' => 'hair-transplant',
'summary' => 'Summary for Hair Transplant Page ',
'description' => 'Description for Hair Transplant Page',
'code' => 'hair_transplant',
'display_order' => 3,
]);
//-- Add Image
$this->uploadImageForPage('p3.jpg', $servicePage);
$servicePage->pageMeta()->create([
'uuid' => Str::uuid(),
'meta_title' => 'Title for Page',
'meta_description' => 'Meta Description for Page',
'meta_keywords' => 'keyword1, keyword2, keyword3',
]);
}
/**************************** Seeders For Team Member Page **********************************/
private function forTeamMemberPage()
{
$servicePage = Page::create([
'uuid' => Str::uuid(),
'title' => 'Doctors & Providers',
'slug' => 'doctor-provider',
'summary' => 'Summary for Team Member Page ',
'description' => 'Description for Team Member Page',
'code' => 'doctor_provider',
'display_order' => 4,
]);
//-- Add Image
$this->uploadImageForPage('p3.jpg', $servicePage);
$servicePage->pageMeta()->create([
'uuid' => Str::uuid(),
'meta_title' => 'Title for Team Member Page',
'meta_description' => 'Meta Description for Team Member Page',
'meta_keywords' => 'keyword1, keyword2, keyword3',
]);
}
/**************************** Seeders For Service Page **********************************/
private function forServicePage()
{
$servicePage = Page::create([
'uuid' => Str::uuid(),
'title' => 'Service',
'slug' => 'service-single',
'summary' => 'Summary for Service Page ',
'description' => 'Description for Service Page',
'code' => 'service',
'display_order' => 5,
]);
//-- Add Image
$this->uploadImageForPage('p3.jpg', $servicePage);
$servicePage->pageMeta()->create([
'uuid' => Str::uuid(),
'meta_title' => 'Title for Service Page',
'meta_description' => 'Meta Description for Service Page',
'meta_keywords' => 'keyword1, keyword2, keyword3',
]);
}
/**************************** Seeders For Blog Page **********************************/
private function forBlogPage()
{
$homePage = Page::create([
'uuid' => Str::uuid(),
'title' => 'blog ',
'slug' => 'blog-single',
'summary' => 'Summary for Blog Page',
'description' => 'Description for Blog Page',
'code' => 'blog',
'display_order' => 6,
]);
//-- Add Image
$this->uploadImageForPage('p6.jpg', $homePage);
$homePage->pageMeta()->create([
'uuid' => Str::uuid(),
'meta_title' => 'Title for Blog Page',
'meta_description' => 'Meta Description for Blog Page',
'meta_keywords' => 'keyword1, keyword2, keyword3',
]);
}
private function uploadImageForPage(string $imageFileName, $cmsbanner)
{
$seederDirPath = 'pages/';
// Generate a unique filename for the new image
$newFileName = Str::uuid() . '.jpg';
// Storage path for the new image
$storagePath = '/pages/' . $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);
$cmsbanner->image = $newFileName;
$cmsbanner->image_path = $storagePath;
$cmsbanner->save();
}
}
}

View File

11
Modules/Page/module.json Normal file
View File

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

15
Modules/Page/package.json Normal file
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

View File

View File

@@ -0,0 +1,37 @@
@extends('admin::layouts.master')
@section('title')
Create Page
@endsection
@section('breadcrumb')
@php
$breadcrumbData = [
[
'title' => 'Page',
'link' => 'null',
],
[
'title' => 'Dashboard',
'link' => route('dashboard'),
],
[
'title' => 'Pages',
'link' => null,
],
[
'title' => 'Add Page',
'link' => null,
],
];
@endphp
@include('admin::layouts.partials.breadcrumb', $breadcrumbData)
@endsection
@section('content')
<div class="row">
<form action="{{ route('cms.pages.store') }}" method="POST" enctype="multipart/form-data">
@csrf
@include('page::partial.form')
</form>
</div>
@endsection

View File

@@ -0,0 +1,39 @@
@extends('admin::layouts.master')
@section('title')
Update Page
@endsection
@section('breadcrumb')
@php
$breadcrumbData = [
[
'title' => 'Page',
'link' => 'null',
],
[
'title' => 'Dashboard',
'link' => route('dashboard'),
],
[
'title' => 'Pages',
'link' => null,
],
[
'title' => 'Update Page',
'link' => null,
],
];
@endphp
@include('admin::layouts.partials.breadcrumb', $breadcrumbData)
@endsection
@section('content')
<div class="row">
<form action="{{ route('cms.pages.update', ['uuid' => $page->uuid]) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('PUT')
@include('page::partial.form')
</form>
</div>
@endsection

View File

@@ -0,0 +1,137 @@
@extends('admin::layouts.master')
@section('title')
Page
@endsection
@section('breadcrumb')
@php
$breadcrumbData = [
[
'title' => 'Page',
'link' => 'null',
],
[
'title' => 'Dashboard',
'link' => route('dashboard'),
],
[
'title' => 'Pages',
'link' => null,
],
];
@endphp
@include('admin::layouts.partials.breadcrumb', $breadcrumbData)
@endsection
@section('content')
<!-- pages List Table -->
<div class="card">
<div class="row">
<div class="col-md-6">
<h4 class="card-header">List of Page</h4>
</div>
<div class="col-md-6">
<div class="flex-column flex-md-row">
<div class="dt-action-buttons text-end pt-3 px-3">
<div class="dt-buttons btn-group flex-wrap">
<a href="{{ route('cms.pages.create') }}"
class="btn btn-secondary create-new btn-primary d-none d-sm-inline-block text-white">
<i class="bx bx-plus me-sm-1"></i>
Add New
</a>
</div>
</div>
</div>
</div>
</div>
<div class="card-datatable table-responsive">
<table class="datatables-users table table-hover border-top">
<thead class="table-light">
<tr>
<th>S.N</th>
<th>Title With Image</th>
<th>Page</th>
<th>Display Order</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody class="table-border-bottom-0">
@if(count($pages) > 0)
@foreach ($pages ?? [] as $page)
<tr>
<td>
#{{ $loop->iteration }}
</td>
<td>
<div class="d-flex align-items-center me-3">
<img src="{{ asset($page->image_path ? 'storage/uploads/' . $page->image_path : 'backend/uploads/images/no-Image.jpg') }}"
alt="Image" class="rounded me-3" height="40" width="60" style="object-fit: cover">
<div class="card-title mb-0">
<h6 class="mb-0 text-capitalize">{{ $page->title }}</h6>
<small class="text-muted">{{ Str::limit($page->summary, 80) }}</small>
</div>
</div>
</td>
<td>
<span class="badge bg-label-primary text-uppercase"> {{ str_replace('_',' ',$page->code) }}</span>
</td>
<td>
{{ $page->display_order }}
</td>
<td>
<span class="badge bg-label-{{ $page->status == 'active' ? 'success' : 'danger' }}">
{{ $page->status }}
</span>
</td>
<td>
<div class="dropdown">
<button type="button" class="btn p-0 dropdown-toggle hide-arrow"
data-bs-toggle="dropdown">
<i class="bx bx-dots-vertical-rounded"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="{{ route('cms.pages.edit', ['uuid' => $page->uuid]) }}">
<i class="bx bx-edit-alt me-1"></i> Edit
</a>
@if($page->code == 'normal')
<form method="POST" action="{{ route('cms.pages.delete', ['uuid' => $page->uuid]) }}"
id="deleteForm_{{ $page->uuid }}" class="dropdown-item">
@csrf
@method('DELETE')
<button type="submit" class="border-0 bg-transparent deleteBtn"
style="color:inherit"><i class="bx bx-trash me-1"></i> Delete</button>
</form>
@endif
</div>
</div>
</td>
</tr>
@endforeach
@else
<tr>
<td colspan="7">No record found.</td>
</tr>
@endif
</tbody>
</table>
</div>
<div class="px-3">
{{ $pages->links('admin::layouts.partials.pagination') }}
</div>
</div>
@endsection
{{-- style --}}
@push('required-styles')
@include('admin::vendor.dataTables.style')
@endpush
{{-- script --}}
@push('required-scripts')
@include('admin::vendor.dataTables.script')
@endpush

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>Page 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-page', 'resources/assets/sass/app.scss') }} --}}
</head>
<body>
@yield('content')
{{-- Vite JS --}}
{{-- {{ module_vite('build-page', 'resources/assets/js/app.js') }} --}}
</body>

View File

@@ -0,0 +1,125 @@
@push('required-styles')
@include('admin::vendor.select2.style')
@endpush
<div class="row">
<div class="col-8">
<div class="card mb-4">
<h5 class="card-header">Basic Details</h5>
<hr class="my-0">
<div class="card-body">
<div class="row" x-data="generateSlug()" x-init="title = '{{ addslashes(old('title', $page->title ?? '')) }}'; slug = '{{ addslashes(old('slug', $page->slug ?? '')) }}';">
<div class="mb-3 col-md-6 fv-plugins-icon-container">
<label for="firstName" class="form-label">Title<span class="text-danger"> *</span></label>
<input class="form-control" type="text" id="firstName" x-model="title" x-on:input="updateSlug()" name="title"
value="{{ old('title', $page->title ?? '') }}" placeholder="e.g:About Us">
<div class="fv-plugins-message-container invalid-feedback"></div>
@if ($errors->has('title'))
<div class="alert alert-danger">{{ $errors->first('title') }}</div>
@endif
</div>
<div class="mb-3 col-md-6 fv-plugins-icon-container">
<label for="lastName" class="form-label">Slug<span class="text-danger"> *</span></label>
<input class="form-control" type="text" x-model="slug" name="slug" id=""
value="{{ old('slug', $page->slug ?? '') }}" placeholder="e.g:about-us">
<div class="fv-plugins-message-container invalid-feedback"></div>
</div>
<div class="mb-3 col-md-12">
<label for="exampleFormControlTextarea1" class="form-label">Summary<span class="text-danger"> *</span></label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="summary"
placeholder="e.g:Summary here..">{{ old('summary', $page->summary ?? '') }}</textarea>
</div>
<div class="mb-3 col-md-12">
<label for="exampleFormControlTextarea1" class="form-label">Description</label>
<textarea class="form-control" id="advance" rows="7" name="description" placeholder="Description here..">{{ old('description', $page->description ?? '') }}</textarea>
</div>
<div class="mt-2">
<button type="submit" class="btn btn-primary me-2"> {{ !isset($page)?'Save Changes':'Update Changes'}}</button>
<button type="reset" class="btn btn-label-secondary">Reset</button>
</div>
</div>
</div>
<!-- /Account -->
</div>
</div>
{{-- Right sidebar --}}
<div class="col-4">
<div class="card mb-4">
<h5 class="card-header">Images</h5>
<div class="card-body">
<div class="d-flex align-items-start align-items-sm-center gap-4">
<img src="{{ asset(!empty($page->image_path)? 'storage/uploads/' . $page->image_path : 'backend/uploads/images/no-Image.jpg') }}" alt="banner-image input-file" class="d-block rounded show-image" height="100" width="100" />
<div class="button-wrapper">
<label for="upload" class="btn btn-sm btn-primary me-2 mb-4" tabindex="0">
<span class="d-none d-sm-block">Upload</span>
<i class="bx bx-upload d-block d-sm-none"></i>
<input type="file" id="upload" class="input-file" name="image" hidden
accept="image/png, image/jpeg" />
</label>
<button type="button" class="btn btn-sm 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.</p>
</div>
</div>
</div>
</div>
<div class="card mb-4">
<h5 class="card-header">Additional Details</h5>
<div class="card-body">
<div class="mb-3 col-md-12">
<label for="organization" class="form-label">Display Order<span class="text-danger"> *</span></label>
<input class="form-control" type="number" name="display_order" id=""
value="{{ old('display_order', $page->display_order ?? '') }}" placeholder="e.g:1">
</div>
<div class="mb-3 col-md-12">
<label for="language" class="form-label">Status<span class="text-danger"> *</span></label>
<div class="position-relative">
<select id="language select2Basic" class="select2 form-select select2-hidden-accessible"
data-select2-id="language" tabindex="-1" aria-hidden="true" name="status">
<option value="" data-select2-id="4">Select Status</option>
<option value="active"
{{ old('status', $page->status ?? '') == 'active' ? 'selected' : '' }}>
Active</option>
<option value="inactive"
{{ old('status', $page->status ?? '') == 'inactive' ? 'selected' : '' }}>Inactive
</option>
</select>
</div>
</div>
</div>
</div>
<div class="card mb-4">
<h5 class="card-header">Meta Details</h5>
<div class="card-body">
<div class="mb-3 col-md-12">
<label for="exampleFormControlTextarea1" class="form-label">Meta Title</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="meta_title">{{ old('meta_title', $page->pageMeta->meta_title ?? '') }}</textarea>
</div>
<div class="mb-3 col-md-12">
<label for="exampleFormControlTextarea1" class="form-label">Meta Description</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="meta_description">{{ old('meta_description', $page->pageMeta->meta_description ?? '') }}</textarea>
</div>
<div class="mb-3 col-md-12">
<label for="exampleFormControlTextarea1" class="form-label">Meta Keywords</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="meta_keywords">{{ old('meta_keywords', $page->pageMeta->meta_keywords ?? '') }}</textarea>
</div>
</div>
</div>
</div>
</div>
@push('required-scripts')
@include('admin::vendor.tinymce.script')
@include('admin::vendor.select2.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('page', fn (Request $request) => $request->user())->name('page');
});

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Support\Facades\Route;
use Modules\Page\app\Http\Controllers\PageController;
/*
|--------------------------------------------------------------------------
| 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' => ['auth'],
'as' => 'cms.',
],
function () {
Route::group(
[
'prefix' => 'cms',
'as' => 'pages.',
'controller' => 'PageController',
],
function () {
Route::get('pages', 'index')->name('index');
Route::get('pages/create', 'create')->name('create');
Route::post('pages/store', 'store')->name('store');
Route::get('pages/{uuid}/edit', 'edit')->name('edit');
Route::put('pages/{uuid}/update', 'update')->name('update');
Route::delete('pages/{uuid}/delete', 'destroy')->name('delete');
}
);
}
);

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-page',
emptyOutDir: true,
manifest: true,
},
plugins: [
laravel({
publicDirectory: '../../public',
buildDirectory: 'build-page',
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',
//];