diff --git a/app/Filament/Resources/BlogResource.php b/app/Filament/Resources/BlogResource.php new file mode 100644 index 0000000..66894b4 --- /dev/null +++ b/app/Filament/Resources/BlogResource.php @@ -0,0 +1,150 @@ +toArray(); + return $form + ->schema([ + Section::make('Post Information') + ->description('Add a new post') + ->schema([ + TextInput::make('post')->label('Post Title') + ->required() + ->live(1) + ->columnSpanFull() + ->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))), + + TextInput::make('slug') + ->required() + ->columnSpan(2), + + Select::make('category_id') + ->relationship('category', 'name') + ->label('Category') + ->searchable() + ->required() + ->preload(10) + ->columnSpan(1), + + Select::make('is_published') + ->options([ + 0 => 'Draft', + 1 => 'Published' + ]) + ->searchable() + ->default(1) + ->required() + ->label('Status') + ->columnSpan(1), + + RichEditor::make('content') + ->label('Page Content') + ->columnSpan(4), + + FileUpload::make('post_image') + ->label('Custom Image (Optional)') + ->directory('media/posts') + ->columnSpan(4) + ->preserveFilenames() + ->image() + ->maxSize(2048), + ]) + ->columns(4), + + Section::make('Customize Post') + ->description('Modifiy Post SEO and Meta Information') + ->schema([ + KeyValue::make('meta') + ->label('Meta (Optional)') + ->keyPlaceholder('Name') + ->valuePlaceholder('Content'), + Textarea::make('custom_header')->rows(6)->label('Custom Header (Optional)'), + + + ]), + + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + TextColumn::make('post')->searchable(), + TextColumn::make('slug'), + TextColumn::make('category.name'), + IconColumn::make('is_published')->label('Published')->boolean(), + TextColumn::make('created_at') + ->label('Created At'), + ]) + ->defaultSort('created_at', 'desc') + ->filters([ + SelectFilter::make('is_published') + ->label('Status') + ->options([ + 0 => 'Draft', + 1 => 'Published', + ]), + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListBlogs::route('/'), + 'create' => Pages\CreateBlog::route('/create'), + 'edit' => Pages\EditBlog::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/BlogResource/Pages/CreateBlog.php b/app/Filament/Resources/BlogResource/Pages/CreateBlog.php new file mode 100644 index 0000000..711fda1 --- /dev/null +++ b/app/Filament/Resources/BlogResource/Pages/CreateBlog.php @@ -0,0 +1,21 @@ +success() + ->title('Post created') + ->body('Post created successfully'); + } +} diff --git a/app/Filament/Resources/BlogResource/Pages/EditBlog.php b/app/Filament/Resources/BlogResource/Pages/EditBlog.php new file mode 100644 index 0000000..df8fd4f --- /dev/null +++ b/app/Filament/Resources/BlogResource/Pages/EditBlog.php @@ -0,0 +1,32 @@ +getResource()::getUrl('index'); + } + + protected function getSavedNotification(): ?Notification + { + return Notification::make() + ->success() + ->title('Post updated') + ->body('Post updated successfully'); + } +} diff --git a/app/Filament/Resources/BlogResource/Pages/ListBlogs.php b/app/Filament/Resources/BlogResource/Pages/ListBlogs.php new file mode 100644 index 0000000..0bee863 --- /dev/null +++ b/app/Filament/Resources/BlogResource/Pages/ListBlogs.php @@ -0,0 +1,19 @@ +schema([ + TextInput::make('name') + ->required() + ->live(1) + ->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))), + TextInput::make('slug')->required(), + Select::make('is_active') + ->options([ + 0 => 'Inactive', + 1 => 'Active', + ]) + ->columnSpanFull() + ->required() + ->default(1) + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + TextColumn::make('name'), + TextColumn::make('slug'), + IconColumn::make('is_active')->label('Active')->boolean(), + ]) + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListCategories::route('/'), + 'create' => Pages\CreateCategory::route('/create'), + 'edit' => Pages\EditCategory::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/CategoryResource/Pages/CreateCategory.php b/app/Filament/Resources/CategoryResource/Pages/CreateCategory.php new file mode 100644 index 0000000..41b42d8 --- /dev/null +++ b/app/Filament/Resources/CategoryResource/Pages/CreateCategory.php @@ -0,0 +1,12 @@ +toArray(); + return $form + ->schema([ + TextInput::make('name') + ->label('Menu Name') + ->required(), + TextInput::make('url') + ->label('URL') + ->url() + ->required(), + Select::make('parent') + ->options($menus) + ->searchable() + ->columnSpanFull() + ->label('Parents (Optional)'), + Toggle::make('new_tab') + ->default(1) + ->label('Open in new tab'), + + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + TextColumn::make('name'), + TextColumn::make('url')->label('URL'), + TextColumn::make('parentname.name')->label('Parent Name'), + IconColumn::make('new_tab')->label('Open in New Tab')->boolean() + ]) + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListMenus::route('/'), + 'create' => Pages\CreateMenu::route('/create'), + 'edit' => Pages\EditMenu::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/MenuResource/Pages/CreateMenu.php b/app/Filament/Resources/MenuResource/Pages/CreateMenu.php new file mode 100644 index 0000000..ec4355f --- /dev/null +++ b/app/Filament/Resources/MenuResource/Pages/CreateMenu.php @@ -0,0 +1,21 @@ +success() + ->title('Menu created') + ->body('Menu created successfully'); + } +} diff --git a/app/Filament/Resources/MenuResource/Pages/EditMenu.php b/app/Filament/Resources/MenuResource/Pages/EditMenu.php new file mode 100644 index 0000000..f497d38 --- /dev/null +++ b/app/Filament/Resources/MenuResource/Pages/EditMenu.php @@ -0,0 +1,32 @@ +getResource()::getUrl('index'); + } + + protected function getSavedNotification(): ?Notification + { + return Notification::make() + ->success() + ->title('Menu updated') + ->body('Menu updated successfully'); + } +} diff --git a/app/Filament/Resources/MenuResource/Pages/ListMenus.php b/app/Filament/Resources/MenuResource/Pages/ListMenus.php new file mode 100644 index 0000000..b475d3f --- /dev/null +++ b/app/Filament/Resources/MenuResource/Pages/ListMenus.php @@ -0,0 +1,19 @@ +toArray(); + + return $form + ->schema([ + + Section::make('Page Information') + ->description('Add a new page') + ->schema([ + TextInput::make('title')->label('Page Title') + ->required() + ->live(1) + ->columnSpanFull() + ->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))), + TextInput::make('slug')->required()->columnSpan(3), + Select::make('is_published') + ->options([ + 0 => 'Draft', + 1 => 'Published' + ]) + ->default(1) + ->required() + ->searchable() + ->label('Status') + ->columnSpan(1), + RichEditor::make('content')->label('Page Content')->columnSpanFull(), + FileUpload::make('page_image') + ->label('Custom Image (Optional)') + ->directory('media/pages') + ->columnSpanFull() + ->preserveFilenames() + ->image() + ->maxSize(2048), + ]) + ->columns(4), + + Section::make('Customize Page') + ->description('Modifiy Page SEO and Meta Information') + ->schema([ + KeyValue::make('meta') + ->label('Meta (Optional)') + ->keyPlaceholder('Name') + ->valuePlaceholder('Content') + ->reorderable(), + Select::make('parent')->options($pages)->label('Parents (Optional)'), + Textarea::make('custom_header')->rows(6)->label('Custom Header (Optional)'), + ]), + + + + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + TextColumn::make('title')->searchable(), + TextColumn::make('slug'), + IconColumn::make('is_published')->label('Published')->boolean(), + TextColumn::make('created_at') + ->label('Created At'), + ]) + ->defaultSort('created_at', 'desc') + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListPages::route('/'), + 'create' => Pages\CreatePage::route('/create'), + 'edit' => Pages\EditPage::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/PageResource/Pages/CreatePage.php b/app/Filament/Resources/PageResource/Pages/CreatePage.php new file mode 100644 index 0000000..2e1ff81 --- /dev/null +++ b/app/Filament/Resources/PageResource/Pages/CreatePage.php @@ -0,0 +1,21 @@ +success() + ->title('Page created') + ->body('Page created successfully'); + } +} diff --git a/app/Filament/Resources/PageResource/Pages/EditPage.php b/app/Filament/Resources/PageResource/Pages/EditPage.php new file mode 100644 index 0000000..0f4b8d3 --- /dev/null +++ b/app/Filament/Resources/PageResource/Pages/EditPage.php @@ -0,0 +1,32 @@ +getResource()::getUrl('index'); + } + + protected function getSavedNotification(): ?Notification + { + return Notification::make() + ->success() + ->title('Page updated') + ->body('Page updated successfully'); + } +} diff --git a/app/Filament/Resources/PageResource/Pages/ListPages.php b/app/Filament/Resources/PageResource/Pages/ListPages.php new file mode 100644 index 0000000..ad90981 --- /dev/null +++ b/app/Filament/Resources/PageResource/Pages/ListPages.php @@ -0,0 +1,19 @@ +route('slug'); + + $publicPath = public_path($slug); + + if (file_exists($publicPath) && is_file($publicPath) && pathinfo($slug, PATHINFO_EXTENSION) === 'php') { + ob_start(); + include($publicPath); + $content = ob_get_clean(); + ob_flush(); + return response($content); + } + + if (file_exists($publicPath) && is_file($publicPath)) { + return response()->file($publicPath); + } + + if (is_dir($publicPath)) { + abort(404); + } + + return $next($request); + } +} diff --git a/app/Livewire/Blog.php b/app/Livewire/Blog.php new file mode 100644 index 0000000..d3f4ce4 --- /dev/null +++ b/app/Livewire/Blog.php @@ -0,0 +1,22 @@ +postDetail = \App\Models\Blog::where('slug', $slug)->firstOrFail(); + $this->category = Category::where('id', $this->postDetail->category_id)->first(); + } + + public function render() + { + return view('livewire.blog')->with('postDetail', $this->postDetail)->with('category', $this->category); + } +} diff --git a/app/Livewire/Page.php b/app/Livewire/Page.php new file mode 100644 index 0000000..9696d9b --- /dev/null +++ b/app/Livewire/Page.php @@ -0,0 +1,28 @@ +slug = $slug; + } + + public function render() + { + $page = \App\Models\Page::where('slug', $this->slug)->firstOrFail(); + + if ($page->is_published == false ) { + abort(404); + } + return view('livewire.page', [ + 'page' => $page, + ]); + } +} diff --git a/app/Models/Blog.php b/app/Models/Blog.php new file mode 100644 index 0000000..9f1320a --- /dev/null +++ b/app/Models/Blog.php @@ -0,0 +1,32 @@ + 'json' + ]; + + public function category(): BelongsTo + { + return $this->belongsTo(Category::class); + } +} diff --git a/app/Models/Category.php b/app/Models/Category.php new file mode 100644 index 0000000..1416f3b --- /dev/null +++ b/app/Models/Category.php @@ -0,0 +1,22 @@ +hasMany(Blog::class); + } +} diff --git a/app/Models/Email.php b/app/Models/Email.php index 1e8f0e5..fb2313f 100644 --- a/app/Models/Email.php +++ b/app/Models/Email.php @@ -72,15 +72,9 @@ class Email extends Model $allowed = explode(',', 'doc,docx,xls,xlsx,ppt,pptx,xps,pdf,dxf,ai,psd,eps,ps,svg,ttf,zip,rar,tar,gzip,mp3,mpeg,wav,ogg,jpeg,jpg,png,gif,bmp,tif,webm,mpeg4,3gpp,mov,avi,mpegs,wmv,flx,txt'); $connection = \App\Models\Email::connectMailBox(); $mailbox = $connection->getMailbox('INBOX'); -// $search = new SearchExpression(); -// $email = "gegsaf@e-pool.co.uk"; -// $search->addCondition(new To($email)); - $messages = $mailbox->getMessages(); - //$messages = $mailbox->getMessages($search, \SORTDATE, true); $result = ''; - foreach ($messages as $message) { $sender = $message->getFrom(); @@ -360,8 +354,6 @@ class Email extends Model public static function deleteBulkMailboxes() { - - $foldersToClean = ['Trash', 'ZDUMP', 'INBOX']; $cutoff = (new \DateTime())->modify('-3 hours'); $totalDeleted = 0; @@ -413,7 +405,6 @@ class Email extends Model public static function mailToDBStatus(): bool { $latestRecord = self::orderBy('timestamp', 'desc')->first(); - if (!$latestRecord) { return false; } @@ -421,7 +412,6 @@ class Email extends Model $currentTime = Carbon::now('UTC'); $lastRecordTime = Carbon::parse($latestRecord->timestamp); - // Check if the last record was added within the last 1 hour if ($lastRecordTime->diffInMinutes($currentTime) < 5) { return true; } diff --git a/app/Models/Menu.php b/app/Models/Menu.php new file mode 100644 index 0000000..ffe1e39 --- /dev/null +++ b/app/Models/Menu.php @@ -0,0 +1,23 @@ +belongsTo(Menu::class, 'parent'); + } +} diff --git a/app/Models/Page.php b/app/Models/Page.php new file mode 100644 index 0000000..61d3bdb --- /dev/null +++ b/app/Models/Page.php @@ -0,0 +1,26 @@ + 'json' + ]; +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index d4653cb..b5b392a 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,8 @@ namespace App\Providers; +use App\Models\Blog; +use App\Models\Menu; use DB; use Illuminate\Support\ServiceProvider; @@ -20,12 +22,20 @@ class AppServiceProvider extends ServiceProvider */ public function boot(): void { - $settings = cache()->remember('app_settings', now()->addMinutes(1), function () { + $settings = cache()->remember('app_settings', now()->addSecond(1), function () { return (array) DB::table('settings')->find(1); }); + $menus = Menu::all(); + $blogs = Blog::where(['is_published' => 1])->get(); if ($settings) { config(['app.settings' => (array) $settings]); } + if ($menus) { + config(['app.menus' => $menus]); + } + if ($blogs) { + config(['app.blogs' => $blogs]); + } } } diff --git a/database/migrations/2025_04_27_120959_create_pages_table.php b/database/migrations/2025_04_27_120959_create_pages_table.php new file mode 100644 index 0000000..1b57a66 --- /dev/null +++ b/database/migrations/2025_04_27_120959_create_pages_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('title'); + $table->string('slug'); + $table->longText('content')->nullable(); + $table->string('parent')->nullable(); + $table->longText('meta')->nullable(); + $table->longText('custom_header')->nullable(); + $table->string('page_image')->nullable(); + $table->boolean('is_published')->default(true); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('pages'); + } +}; diff --git a/database/migrations/2025_04_27_123300_create_menus_table.php b/database/migrations/2025_04_27_123300_create_menus_table.php new file mode 100644 index 0000000..3345268 --- /dev/null +++ b/database/migrations/2025_04_27_123300_create_menus_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('name'); + $table->string('url'); + $table->boolean('new_tab'); + $table->string('parent')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('menus'); + } +}; diff --git a/database/migrations/2025_04_27_133659_create_categories_table.php b/database/migrations/2025_04_27_133659_create_categories_table.php new file mode 100644 index 0000000..21032e5 --- /dev/null +++ b/database/migrations/2025_04_27_133659_create_categories_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('name'); + $table->string('slug'); + $table->boolean('is_active'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('categories'); + } +}; diff --git a/database/migrations/2025_04_27_133802_create_blogs_table.php b/database/migrations/2025_04_27_133802_create_blogs_table.php new file mode 100644 index 0000000..0386f5c --- /dev/null +++ b/database/migrations/2025_04_27_133802_create_blogs_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('post'); + $table->string('slug'); + $table->longText('content')->nullable(); + $table->longText('meta')->nullable(); + $table->longText('custom_header')->nullable(); + $table->string('post_image')->nullable(); + $table->boolean('is_published')->default(true); + $table->foreignId('category_id')->constrained('categories')->cascadeOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('blogs'); + } +}; diff --git a/resources/views/components/layouts/app.blade.php b/resources/views/components/layouts/app.blade.php index 1dedfb2..d71a92d 100644 --- a/resources/views/components/layouts/app.blade.php +++ b/resources/views/components/layouts/app.blade.php @@ -6,20 +6,32 @@
-
- © {{ config('app.settings.app_name') }}
@@ -180,5 +194,7 @@ }, 1000); }); + {!! config('app.settings.app_footer') !!} + @yield('custom_header')