Add all files

This commit is contained in:
root
2025-11-30 11:57:22 +01:00
parent 2ee51cac4f
commit 044271db3d
1476 changed files with 142544 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
<?php
namespace Paymenter\Extensions\Others\CustomPages\Admin\Resources;
use Filament\Forms;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Support\Str;
use Paymenter\Extensions\Others\CustomPages\Admin\Resources\CustomPagesResource\Pages;
use Paymenter\Extensions\Others\CustomPages\Models\Page;
class CustomPagesResource extends Resource
{
protected static ?string $model = Page::class;
protected static ?string $navigationIcon = 'heroicon-m-newspaper';
protected static ?string $navigationGroup = 'Custom Pages';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('title')
->label('Title')
->required()
->maxLength(255)
->live(onBlur: true)
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
if (($get('slug') ?? '') !== Str::slug($old)) {
return;
}
$set('slug', Str::slug($state));
})
->placeholder('Fill in the title for your page'),
Forms\Components\TextInput::make('slug')
->label('Slug')
->required()
->maxLength(255)
->placeholder('URL-friendly slug for the page, e.g. about-us'),
Forms\Components\DateTimePicker::make('expires_at')
->label('Expires at')
->placeholder('Optional expiration date')
->nullable()
->helperText('If set, the page will become unavailable after this date.'),
Forms\Components\Select::make('visibility')
->label('Visibility')
->options([
'everyone' => 'Everyone',
'guests' => 'Only people who are not logged in',
'logged-in' => 'Everyone who is logged in',
'customers' => 'Customers only',
'admins' => 'Admins only',
])
->default('everyone')
->required()
->helperText('Choose who can see your page'),
Toggle::make('is_active')
->label('Published')
->default(true)
->helperText('Toggle if the page is enabled'),
Toggle::make('visible_in_menu')
->label('Visible in navigationbar')
->helperText('Toggle if the page is shown in the navigationbar'),
Forms\Components\MarkdownEditor::make('content')
->label('Content')
->required()
->columnSpanFull()
->placeholder('Enter the content of the page (supports markdown)'),
Forms\Components\Section::make('Metadata')
->schema([
Forms\Components\TextInput::make('meta_title')
->label('Meta Title')
->placeholder('Custom title for SEO and embeds'),
Forms\Components\Textarea::make('meta_description')
->label('Meta Description')
->placeholder('Short description of the page'),
Forms\Components\ColorPicker::make('meta_color')
->label('Meta Color')
->placeholder('#ff6600'),
Forms\Components\FileUpload::make('meta_image')
->label('Meta Image')
->image()
->directory('meta-images'),
Forms\Components\FileUpload::make('meta_favicon')
->label('Meta Favicon')
->image()
->directory('meta-favicons'),
])
->columns(2)
->collapsible()
->collapsed(),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('slug')
->label('Slug')
->sortable(),
Tables\Columns\TextColumn::make('visibility')
->label('Visibility')
->sortable()
->formatStateUsing(fn ($state) => ucfirst($state)),
Tables\Columns\IconColumn::make('is_active')
->label('Active')
->boolean()
->sortable(),
Tables\Columns\IconColumn::make('visible_in_menu')
->label('On navigationbar')
->boolean()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->label('Last updated')
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('views_count')
->label('Views')
->getStateUsing(fn (Page $record) => $record->views()->count())
->sortable(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getPages(): array
{
return [
'index' => Pages\ListCustomPages::route('/'),
'create' => Pages\CreateCustomPages::route('/create'),
'edit' => Pages\EditCustomPages::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Paymenter\Extensions\Others\CustomPages\Admin\Resources\CustomPagesResource\Pages;
use Filament\Resources\Pages\CreateRecord;
use Paymenter\Extensions\Others\CustomPages\Admin\Resources\CustomPagesResource;
class CreateCustomPages extends CreateRecord
{
protected static string $resource = CustomPagesResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Paymenter\Extensions\Others\CustomPages\Admin\Resources\CustomPagesResource\Pages;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
use Paymenter\Extensions\Others\CustomPages\Admin\Resources\CustomPagesResource;
class EditCustomPages extends EditRecord
{
protected static string $resource = CustomPagesResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Paymenter\Extensions\Others\CustomPages\Admin\Resources\CustomPagesResource\Pages;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Paymenter\Extensions\Others\CustomPages\Admin\Resources\CustomPagesResource;
class ListCustomPages extends ListRecords
{
protected static string $resource = CustomPagesResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,112 @@
<?php
namespace Paymenter\Extensions\Others\CustomPages;
use App\Classes\Extension\Extension;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\View;
use Illuminate\Support\HtmlString;
use Paymenter\Extensions\Others\CustomPages\Admin\Resources\CustomPagesResource;
use Paymenter\Extensions\Others\CustomPages\Models\Page;
class CustomPages extends Extension
{
public function getConfig($values = [])
{
try {
return [
[
'name' => 'Notice',
'type' => 'placeholder',
'label' => new HtmlString(
'Use this extension to create Custom Pages like a ToS, FAQ or Privacy Policy.
Manage your Pages at <a class="text-primary-600" href="' . CustomPagesResource::getUrl() . '">Custom Pages</a>.
<br><br><small><i>Need help? Join our Discord at <a href="https://discord.gg/V3nJ3jVURN">https://discord.gg/V3nJ3jVURN</a></small></i>'
),
],
];
} catch (\Exception $e) {
return [
[
'name' => 'Notice',
'type' => 'placeholder',
'label' => new HtmlString(
'Use this extension to create Custom Pages like a ToS, FAQ or Privacy Policy. You will need to enable it before you can use it.
<br><br><small><i>Need help? Join our Discord at <a href="https://discord.gg/V3nJ3jVURN">https://discord.gg/V3nJ3jVURN</a></small></i>'
),
],
];
}
}
public function enabled()
{
Artisan::call('migrate', [
'--path' => 'extensions/Others/CustomPages/database/migrations',
'--force' => true,
]);
}
public function boot()
{
require __DIR__ . '/routes/web.php';
View::addNamespace('custompages', __DIR__ . '/resources/views');
\Livewire\Livewire::component('custompages.show', \Paymenter\Extensions\Others\CustomPages\Livewire\Show::class);
Event::listen('navigation', function () {
return Page::where('visible_in_menu', true)
->where('is_active', true)
->whereNotNull('slug')
->where('slug', '!=', '')
->get()
->filter(function ($page) {
switch ($page->visibility) {
case 'admins':
if (!Auth::check() || is_null(Auth::user()->role)) {
return false;
}
break;
case 'customers':
if (!Auth::check() || !is_null(Auth::user()->role)) {
return false;
}
break;
case 'guests':
if (Auth::check()) {
return false;
}
break;
case 'logged-in':
if (!Auth::check()) {
return false;
}
break;
case 'everyone':
default:
// everyone mag zien
break;
}
return true; // fucked up
})
->map(function ($page) {
return [
'route' => 'custompages.show',
'name' => $page->title,
'params' => ['fallbackPlaceholder' => $page->slug],
'icon' => 'ri-pages',
];
})
->toArray();
});
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace Paymenter\Extensions\Others\CustomPages\Livewire;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Request;
use Livewire\Component;
use Paymenter\Extensions\Others\CustomPages\Models\Page as ModelsPage;
use Paymenter\Extensions\Others\CustomPages\Models\PageView;
class Show extends Component
{
public ModelsPage $page;
public function mount()
{
$slug = request()->path();
$this->page = ModelsPage::where('slug', $slug)->firstOrFail();
// Pagina actief ja of nee
if (!$this->page->is_active) {
abort(404);
}
// check voor expire
if ($this->page->expires_at && now()->greaterThan($this->page->expires_at)) {
abort(404);
}
// Toegangscontrole
switch ($this->page->visibility) {
case 'admins':
if (!Auth::check() || is_null(Auth::user()->role)) {
abort(404);
}
break;
case 'customers':
if (!Auth::check() || !is_null(Auth::user()->role)) {
abort(404);
}
break;
case 'guests':
if (Auth::check()) {
abort(404);
}
break;
case 'logged-in':
if (!Auth::check()) {
abort(404);
}
break;
case 'everyone':
default:
// iedereen
break;
}
// Pageviews
PageView::create([
'page_id' => $this->page->id,
'ip_address' => Request::ip(),
'user_agent' => Request::header('User-Agent'),
'viewed_at' => now(),
]);
}
public function render()
{
return view('custompages::show', [
'page' => $this->page,
])->layout('layouts.app', [
'title' => $this->page->meta_title ?? $this->page->title,
'description' => $this->page->meta_description ?? '',
'image' => $this->page->meta_image ?? null,
'color' => $this->page->meta_color ?? null,
'favicon' => $this->page->meta_favicon ?? null,
]);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Paymenter\Extensions\Others\CustomPages\Models;
use Illuminate\Database\Eloquent\Model;
class Page extends Model
{
protected $table = 'ext_custompages_pages';
protected $fillable = [
'is_active',
'expires_at',
'title',
'slug',
'content',
'visibility',
'visible_in_menu',
// metadata
'meta_title',
'meta_description',
'meta_image',
'meta_color',
'meta_favicon',
];
protected $casts = [
'visible_in_menu' => 'boolean',
'is_active' => 'boolean',
];
public function getRouteKeyName()
{
return 'slug';
}
public function views()
{
return $this->hasMany(PageView::class);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Paymenter\Extensions\Others\CustomPages\Models;
use Illuminate\Database\Eloquent\Model;
class PageView extends Model
{
protected $table = 'page_views';
public $timestamps = false;
protected $fillable = [
'page_id',
'ip_address',
'user_agent',
'viewed_at',
];
protected $casts = [
'viewed_at' => 'datetime',
];
public function page()
{
return $this->belongsTo(Page::class);
}
}

View File

@@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('ext_custompages_pages', function (Blueprint $table) {
$table->engine = 'InnoDB';
// content
$table->id();
$table->string('title');
$table->string('slug')->unique();
$table->text('content');
// toegang
$table->enum('visibility', [
'everyone',
'customers',
'admins',
'guests',
'logged-in',
])->default('everyone');
// menu en published
$table->boolean('visible_in_menu')->default(false);
$table->boolean('is_active')->default(true);
// expiry
$table->timestamp('expires_at')->nullable();
// metadata
$table->string('meta_title')->nullable()->after('title');
$table->text('meta_description')->nullable()->after('meta_title');
$table->string('meta_image')->nullable()->after('meta_description');
$table->string('meta_color')->nullable()->after('meta_image');
$table->string('meta_favicon')->nullable()->after('meta_color');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('ext_custompages_pages');
}
};

View File

@@ -0,0 +1,25 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('page_views', function (Blueprint $table) {
$table->id();
$table->foreignId('page_id')->constrained('ext_custompages_pages')->onDelete('cascade');
$table->ipAddress('ip_address');
$table->string('user_agent')->nullable();
$table->timestamp('viewed_at')->useCurrent();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('page_views');
}
};

View File

@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OS-Services CustomPages Addon Installation</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="https://cdn.os-services.nl/u/r0uzJU.png" />
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
color: #333;
}
header {
background-color: #24d97f;
color: white;
padding: 2rem;
text-align: center;
}
.container {
max-width: 800px;
margin: 2rem auto;
background: white;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
padding: 2rem;
}
.step {
margin-bottom: 2rem;
}
.step h2 {
color: #24d97f;
}
.step img {
width: 100%;
max-height: 300px;
object-fit: contain;
border: 1px solid #ddd;
border-radius: 6px;
margin-top: 1rem;
}
footer {
text-align: center;
margin-top: 3rem;
font-size: 0.9rem;
color: #666;
}
code {
background-color: #eee;
padding: 0.2rem 0.4rem;
border-radius: 4px;
font-family: monospace;
}
.highlight {
background-color: #eaf4ff;
padding: 1rem;
border-left: 4px solid #24d97f;
margin-top: 1rem;
border-radius: 4px;
}
.discord {
margin-top: 1rem;
background-color: #24d97f;
color: white;
padding: 1rem;
text-align: center;
border-radius: 8px;
}
.discord a {
color: white;
text-decoration: underline;
font-weight: bold;
}
</style>
</head>
<body>
<header>
<h1>OS-Services CustomPages Installation</h1>
<p>Thank you root0091 for your purchase!</p>
</header>
<div class="container">
<div class="step">
<h2>Step 1: Upload the Folder</h2>
<p>Upload the <code>CustomPages</code> folder to the following directory on your server:</p>
<div class="highlight"><code>/var/www/paymenter/extensions/Others</code></div>
<img src="https://cdn.os-services.nl/u/o2PHEG.png" alt="Upload Folder">
</div>
<div class="step">
<h2>Step 2: Enable the Extension</h2>
<p>In your admin panel, go to <strong>Extensions</strong> and enable <code>CustomPages</code>.</p>
<img src="https://cdn.os-services.nl/u/aCBIii.png" alt="Enable Extension">
</div>
<div class="step">
<h2>Step 3: Manage Pages</h2>
<p>In the admin sidebar, a new tab named <strong>Custom Pages</strong> will appear. Click it to start creating and managing your pages!</p>
<img src="https://cdn.os-services.nl/u/ifcC9n.png" alt="Pages Tab">
</div>
<div class="discord">
<p>Need help? Join our <a href="https://discord.gg/V3nJ3jVURN" target="_blank">Discord Server</a> and open a ticket.</p>
<p>Please include your Buyers ID: <strong>deff45979c7115b9b0534c06b9f51dd6</strong></p>
</div>
</div>
<footer>
&copy; 2025 OS-Services CustomPages Addon – All rights reserved.
</footer>
<br>
</body>
</html>

View File

@@ -0,0 +1,7 @@
<div class="mx-auto container mt-4">
<div class="bg-background-secondary hover:bg-background-secondary/80 border border-neutral p-4 rounded-lg">
<article class="prose dark:prose-invert mb-2 max-w-full">
{!! \Illuminate\Support\Str::markdown($page->content) !!}
</article>
</div>
</div>

View File

@@ -0,0 +1,6 @@
<?php
use Illuminate\Support\Facades\Route;
use Paymenter\Extensions\Others\CustomPages\Livewire\Show;
Route::fallback(Show::class)->middleware('web')->name('custompages.show');