Initial commit

This commit is contained in:
root
2026-05-09 17:28:23 +02:00
commit 9d73f82529
5575 changed files with 281989 additions and 0 deletions
+241
View File
@@ -0,0 +1,241 @@
<?php
declare(strict_types=1);
/**
* @phpstan-type AuthUser = \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable|null
*/
namespace App\Filament\Resources\Atom\Articles;
use App\Filament\Resources\Atom\Articles\Pages\CreateArticle;
use App\Filament\Resources\Atom\Articles\Pages\EditArticle;
use App\Filament\Resources\Atom\Articles\Pages\ListArticles;
use App\Filament\Resources\Atom\Articles\Pages\ViewArticle;
use App\Filament\Resources\Atom\Articles\RelationManagers\TagsRelationManager;
use App\Filament\Traits\TranslatableResource;
use App\Models\Articles\WebsiteArticle;
use Exception;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ForceDeleteAction;
use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreAction;
use Filament\Actions\RestoreBulkAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Facades\Auth;
class ArticleResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = WebsiteArticle::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-newspaper';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'website/articles';
public static string $translateIdentifier = 'articles';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components(static::getForm());
}
public static function getForm(): array
{
return [
Tabs::make('Main')
->tabs([
Tab::make(__('filament::resources.tabs.Home'))
->icon('heroicon-o-home')
->schema([
TextInput::make('title')
->label(__('filament::resources.inputs.title'))
->required()
->autocomplete()
->maxLength(255)
->columnSpan('full'),
TextInput::make('short_story')
->label(__('filament::resources.inputs.description'))
->required()
->maxLength(255)
->autocomplete()
->columnSpan('full'),
FileUpload::make('image')
->label(__('filament::resources.inputs.image'))
->directory('website_news_images')
->visibility('public'),
RichEditor::make('full_story')
->label(__('filament::resources.inputs.content'))
->required()
->columnSpan('full'),
Hidden::make('user_id')
->default(Auth::id() ?? 0),
]),
Tab::make(__('filament::resources.tabs.Configurations'))
->icon('heroicon-o-cog')
->schema([
Toggle::make('is_visible')
->label(__('filament::resources.inputs.visible'))
->onIcon('heroicon-s-check')
->offIcon('heroicon-s-x-mark')
->default(true)
->live()
->afterStateUpdated(function (string $operation, $state, $record) {
/** @var WebsiteArticle $record */
if ($operation !== 'edit' || ! $record instanceof WebsiteArticle) {
return;
}
try {
if ($state) {
$record->restore();
} else {
$record->delete();
}
} catch (Exception $e) {
report($e);
}
})
->formatStateUsing(function ($record) {
if (is_null($record)) {
return true;
}
return is_null($record->deleted_at);
}),
Toggle::make('can_comment')
->onIcon('heroicon-s-check')
->label(__('filament::resources.inputs.allow_comments'))
->default(true)
->offIcon('heroicon-s-x-mark'),
]),
])->columnSpanFull(),
];
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->defaultSort('id', 'desc')
->poll('60s')
->columns(static::getTable())
->filters([
TrashedFilter::make(),
])
->recordActions([
ViewAction::make(),
EditAction::make(),
DeleteAction::make(),
RestoreAction::make(),
ForceDeleteAction::make(),
])
->toolbarActions([
DeleteBulkAction::make(),
RestoreBulkAction::make(),
ForceDeleteBulkAction::make(),
]);
}
public static function getTable(): array
{
return [
TextColumn::make('id')
->label(__('filament::resources.columns.id')),
ImageColumn::make('image')
->circular()
->extraAttributes(['style' => 'image-rendering: pixelated'])
->size(50)
->label(__('filament::resources.columns.image')),
TextColumn::make('title')
->label(__('filament::resources.columns.title'))
->searchable()
->limit(50),
TextColumn::make('user.username')
->searchable()
->label(__('filament::resources.columns.by')),
ToggleColumn::make('is_visible')
->label(__('filament::resources.columns.visible'))
->onIcon('heroicon-s-check')
->toggleable()
->state(fn ($record) => is_null($record->deleted_at))
->disabled(),
ToggleColumn::make('allow_comments')
->label(__('filament::resources.columns.allow_comments'))
->onIcon('heroicon-s-check')
->toggleable()
->disabled(),
];
}
#[\Override]
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
#[\Override]
public static function getRelations(): array
{
return [
TagsRelationManager::class,
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListArticles::route('/'),
'create' => CreateArticle::route('/create'),
'view' => ViewArticle::route('/{record}'),
'edit' => EditArticle::route('/{record}/edit'),
];
}
#[\Override]
public static function getGlobalSearchEloquentQuery(): Builder
{
return parent::getGlobalSearchEloquentQuery()->withTrashed();
}
}
@@ -0,0 +1,25 @@
<?php
namespace App\Filament\Resources\Atom\Articles\Pages;
use App\Filament\Resources\Atom\Articles\ArticleResource;
use App\Models\Article;
use Filament\Resources\Pages\CreateRecord;
class CreateArticle extends CreateRecord
{
#[\Override]
protected static string $resource = ArticleResource::class;
protected function afterCreate(): void
{
/** @var null|Article $articleCreated */
$articleCreated = $this->getRecord();
if (! $articleCreated || ! $articleCreated->visible) {
return;
}
$articleCreated->createFollowersNotification();
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Articles\Pages;
use App\Filament\Resources\Atom\Articles\ArticleResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditArticle extends EditRecord
{
#[\Override]
protected static string $resource = ArticleResource::class;
#[\Override]
protected function getActions(): array
{
return [
DeleteAction::make(),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Articles\Pages;
use App\Filament\Resources\Atom\Articles\ArticleResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListArticles extends ListRecords
{
#[\Override]
protected static string $resource = ArticleResource::class;
#[\Override]
protected function getActions(): array
{
return [
CreateAction::make(),
];
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\Filament\Resources\Atom\Articles\Pages;
use App\Filament\Resources\Atom\Articles\ArticleResource;
use App\Models\Article;
use Filament\Actions\Action;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ViewRecord;
use Illuminate\Support\Facades\Auth;
class ViewArticle extends ViewRecord
{
#[\Override]
protected static string $resource = ArticleResource::class;
#[\Override]
public function getHeaderActions(): array
{
return [
Action::make('Send Notification')
->label(__('Send notifications'))
->color('gray')
->visible(fn (Article $record) => $record->user_id === Auth::id())
->requiresConfirmation()
->action(function (Article $record) {
$record->createFollowersNotification();
}),
EditAction::make(),
];
}
}
@@ -0,0 +1,62 @@
<?php
namespace App\Filament\Resources\Atom\Articles\RelationManagers;
use App\Filament\Resources\Atom\Tags\TagResource;
use App\Filament\Traits\TranslatableResource;
use Filament\Actions\AttachAction;
use Filament\Actions\CreateAction;
use Filament\Actions\DetachAction;
use Filament\Actions\DetachBulkAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\TextInput;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
class TagsRelationManager extends RelationManager
{
use TranslatableResource;
#[\Override]
protected static string $relationship = 'tags';
#[\Override]
protected static ?string $recordTitleAttribute = 'name';
public static string $translateIdentifier = 'tags';
#[\Override]
public function form(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('name')
->required()
->maxLength(255),
]);
}
public function table(Table $table): Table
{
return $table
->columns(TagResource::getTable())
->modifyQueryUsing(fn ($query) => $query->latest())
->filters([
//
])
->headerActions([
CreateAction::make()
->schema(TagResource::getForm()),
AttachAction::make()->preloadRecordSelect(),
])
->recordActions([
ViewAction::make(),
DetachAction::make(),
])
->toolbarActions([
DetachBulkAction::make(),
]);
}
}
@@ -0,0 +1,101 @@
<?php
namespace App\Filament\Resources\Atom\CameraWebs;
use App\Filament\Resources\Atom\CameraWebs\Pages\EditCameraWeb;
use App\Filament\Resources\Atom\CameraWebs\Pages\ListCameraWeb;
use App\Models\Miscellaneous\CameraWeb;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;
class CameraWebResource extends Resource
{
#[\Override]
protected static ?string $model = CameraWeb::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-photo';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'camera-web';
#[\Override]
protected static ?string $pluralModelLabel = 'photos';
#[\Override]
protected static ?string $navigationLabel = 'Web Camera';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components([
Toggle::make('visible')
->label(__('Visible'))
->default(true),
]);
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->defaultSort('id', 'desc')
->columns([
TextColumn::make('id')
->label(__('filament::resources.columns.id'))
->sortable(),
TextColumn::make('user_id')
->label(__('filament::resources.columns.user_id')),
TextColumn::make('room_id')
->label(__('filament::resources.columns.room_id')),
TextColumn::make('timestamp')
->label(__('filament::resources.columns.created_at'))
->dateTime(),
ImageColumn::make('url')
->label(__('filament::resources.columns.image'))
->extraAttributes(['style' => 'image-rendering: pixelated'])
->size(125),
ToggleColumn::make('visible')
->label(__('Visible')),
])
->recordActions([
DeleteAction::make(),
])
->toolbarActions([
DeleteBulkAction::make(),
]);
}
#[\Override]
public static function getRelations(): array
{
return [
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListCameraWeb::route('/'),
'edit' => EditCameraWeb::route('/{record}/edit'),
];
}
#[\Override]
public static function canCreate(): bool
{
return false;
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\CameraWebs\Pages;
use App\Filament\Resources\Atom\CameraWebs\CameraWebResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditCameraWeb extends EditRecord
{
#[\Override]
protected static string $resource = CameraWebResource::class;
#[\Override]
protected function getHeaderActions(): array
{
return [
DeleteAction::make(),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\CameraWebs\Pages;
use App\Filament\Resources\Atom\CameraWebs\CameraWebResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListCameraWeb extends ListRecords
{
#[\Override]
protected static string $resource = CameraWebResource::class;
#[\Override]
protected function getHeaderActions(): array
{
return [
CreateAction::make(),
];
}
}
@@ -0,0 +1,117 @@
<?php
namespace App\Filament\Resources\Atom\CmsSettings;
use App\Filament\Resources\Atom\CmsSettings\Pages\ManageCmsSettings;
use App\Filament\Traits\TranslatableResource;
use App\Models\Miscellaneous\WebsiteSetting;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class CmsSettingResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = WebsiteSetting::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-cpu-chip';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'website/cms-settings';
public static string $translateIdentifier = 'cms-settings';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components([
Section::make()
->schema([
TextInput::make('key')
->label(__('filament::resources.inputs.key'))
->maxLength(50)
->autocomplete()
->unique(ignoreRecord: true)
->required(),
TextInput::make('value')
->label(__('filament::resources.inputs.value'))
->required()
->maxLength(255)
->autocomplete(),
TextInput::make('comment')
->label(__('filament::resources.inputs.comment'))
->nullable()
->maxLength(255)
->autocomplete()
->columnSpanFull(),
])
->columns([
'sm' => 2,
]),
]);
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->defaultSort('id', 'desc')
->columns([
TextColumn::make('key')
->label(__('filament::resources.columns.key'))
->searchable(),
TextColumn::make('value')
->label(__('filament::resources.columns.value'))
->searchable()
->limit(30),
TextColumn::make('comment')
->label(__('filament::resources.columns.comment'))
->toggleable()
->searchable()
->tooltip(function (TextColumn $column): ?string {
$state = $column->getState();
if (! is_string($state) || strlen($state) <= $column->getCharacterLimit()) {
return null;
}
return $state;
})
->limit(60),
])
->filters([
//
])
->recordActions([
EditAction::make(),
DeleteAction::make(),
])
->toolbarActions([
// ...
]);
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ManageCmsSettings::route('/'),
];
}
}
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\CmsSettings\Pages;
use App\Filament\Resources\Atom\CmsSettings\CmsSettingResource;
use Filament\Actions\Action;
use Filament\Actions\CreateAction;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\ManageRecords;
use Illuminate\Support\Facades\Cache;
class ManageCmsSettings extends ManageRecords
{
#[\Override]
protected static string $resource = CmsSettingResource::class;
#[\Override]
protected function getActions(): array
{
return [
Action::make('reload_cache')
->label('Reload Cache')
->icon('heroicon-o-arrow-path')
->color('warning')
->requiresConfirmation()
->modalHeading('Reload Settings Cache')
->modalDescription('This will clear and reload the website settings cache. The cache will be automatically rebuilt on the next request.')
->modalSubmitActionLabel('Reload Cache')
->action(function () {
Cache::forget('website_settings');
Notification::make()
->success()
->title('Cache Cleared')
->body('Settings cache has been cleared successfully.')
->send();
}),
CreateAction::make(),
];
}
protected function getTableRecordsPerPageSelectOptions(): array
{
return [25, 50, 100];
}
}
@@ -0,0 +1,127 @@
<?php
namespace App\Filament\Resources\Atom;
use App\Filament\Resources\Atom\HelpQuestionCategoryResource\Pages\CreateHelpQuestionCategory;
use App\Filament\Resources\Atom\HelpQuestionCategoryResource\Pages\EditHelpQuestionCategory;
use App\Filament\Resources\Atom\HelpQuestionCategoryResource\Pages\ListHelpQuestionCategories;
use App\Filament\Traits\TranslatableResource;
use App\Models\Help\WebsiteHelpCenterCategory;
use Filament\Forms\Components\ColorPicker;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;
class HelpQuestionCategoryResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = WebsiteHelpCenterCategory::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-folder';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Help Center';
#[\Override]
protected static ?string $slug = 'help/categories';
public static string $translateIdentifier = 'help-categories';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components(static::getForm());
}
public static function getForm(): array
{
return [
TextInput::make('name')
->label(__('Name'))
->required()
->maxLength(255)
->helperText(__('Use :hotel for dynamic hotel name')),
Textarea::make('content')
->label(__('Content'))
->rows(8)
->helperText(__('Use :hotel for dynamic hotel name. Use <br/> for line breaks.')),
TextInput::make('image_url')
->label(__('Image URL'))
->maxLength(255),
TextInput::make('button_text')
->label(__('Button Text'))
->maxLength(255),
TextInput::make('button_url')
->label(__('Button URL'))
->maxLength(255),
ColorPicker::make('button_color')
->label(__('Button Color')),
ColorPicker::make('button_border_color')
->label(__('Button Border Color')),
Toggle::make('small_box')
->label(__('Small Box'))
->helperText(__('Show as small box on the right side')),
TextInput::make('position')
->label(__('Position'))
->numeric()
->default(0),
];
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->columns(static::getTable());
}
public static function getTable(): array
{
return [
TextColumn::make('id')
->label(__('ID'))
->sortable(),
TextColumn::make('name')
->label(__('Name'))
->searchable(),
TextColumn::make('button_text')
->label(__('Button Text')),
ToggleColumn::make('small_box')
->label(__('Small Box')),
TextColumn::make('position')
->label(__('Position'))
->sortable(),
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListHelpQuestionCategories::route('/'),
'create' => CreateHelpQuestionCategory::route('/create'),
'edit' => EditHelpQuestionCategory::route('/{record}/edit'),
];
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HelpQuestionCategoryResource\Pages;
use App\Filament\Resources\Atom\HelpQuestionCategoryResource;
use Filament\Resources\Pages\CreateRecord;
class CreateHelpQuestionCategory extends CreateRecord
{
#[\Override]
protected static string $resource = HelpQuestionCategoryResource::class;
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HelpQuestionCategoryResource\Pages;
use App\Filament\Resources\Atom\HelpQuestionCategoryResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditHelpQuestionCategory extends EditRecord
{
#[\Override]
protected static string $resource = HelpQuestionCategoryResource::class;
#[\Override]
protected function getActions(): array
{
return [
DeleteAction::make(),
];
}
}
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HelpQuestionCategoryResource\Pages;
use App\Filament\Resources\Atom\HelpQuestionCategoryResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListHelpQuestionCategories extends ListRecords
{
#[\Override]
protected static string $resource = HelpQuestionCategoryResource::class;
#[\Override]
protected function getActions(): array
{
return [
CreateAction::make(),
];
}
protected function getTableReorderColumn(): ?string
{
return 'order';
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HelpQuestionCategoryResource\Pages;
use App\Filament\Resources\Atom\HelpQuestionCategoryResource;
use Filament\Resources\Pages\ViewRecord;
class ViewHelpQuestionCategory extends ViewRecord
{
#[\Override]
protected static string $resource = HelpQuestionCategoryResource::class;
}
@@ -0,0 +1,52 @@
<?php
namespace App\Filament\Resources\Atom\HelpQuestionCategoryResource\RelationManagers;
use App\Filament\Resources\Atom\HelpQuestionResource;
use App\Filament\Traits\TranslatableResource;
use Filament\Actions\AttachAction;
use Filament\Actions\DetachAction;
use Filament\Actions\DetachBulkAction;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
class QuestionsRelationManager extends RelationManager
{
use TranslatableResource;
#[\Override]
protected static string $relationship = 'questions';
#[\Override]
protected static ?string $recordTitleAttribute = 'title';
public static string $translateIdentifier = 'help-questions';
#[\Override]
protected static ?string $inverseRelationship = 'categories';
#[\Override]
public function form(Schema $schema): Schema
{
return $schema->components(HelpQuestionResource::getForm(true));
}
public function table(Table $table): Table
{
return $table->columns(HelpQuestionResource::getTable())
->modifyQueryUsing(fn ($query) => $query->latest())
->filters([
//
])
->headerActions([
AttachAction::make(),
])
->recordActions([
DetachAction::make(),
])
->toolbarActions([
DetachBulkAction::make(),
]);
}
}
+128
View File
@@ -0,0 +1,128 @@
<?php
namespace App\Filament\Resources\Atom;
use App\Filament\Resources\Atom\HelpQuestionResource\Pages\CreateHelpQuestion;
use App\Filament\Resources\Atom\HelpQuestionResource\Pages\EditHelpQuestion;
use App\Filament\Resources\Atom\HelpQuestionResource\Pages\ListHelpQuestions;
use App\Filament\Resources\Atom\HelpQuestionResource\Pages\ViewHelpQuestion;
use App\Filament\Resources\Atom\HelpQuestionResource\RelationManagers\CategoriesRelationManager;
use App\Filament\Traits\TranslatableResource;
use App\Models\Help\WebsiteHelpCenterTicket;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;
class HelpQuestionResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = WebsiteHelpCenterTicket::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-question-mark-circle';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Help Center';
#[\Override]
protected static ?string $slug = 'help/questions';
public static string $translateIdentifier = 'help-questions';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components(static::getForm());
}
public static function getForm(bool $forRelationManager = false): array
{
return [
TextInput::make('title')
->label(__('Title'))
->required()
->maxLength(255),
Textarea::make('content')
->label(__('Content'))
->required(),
Select::make('category_id')
->label(__('Category'))
->relationship('category', 'name')
->required()
->visible(! $forRelationManager),
Select::make('user_id')
->label(__('User'))
->relationship('user', 'username')
->required(),
Toggle::make('open')
->label(__('Open'))
->default(true),
];
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->columns(static::getTable());
}
public static function getTable(): array
{
return [
TextColumn::make('id')
->label(__('ID'))
->sortable(),
TextColumn::make('title')
->label(__('Title'))
->searchable(),
TextColumn::make('user.username')
->label(__('User'))
->searchable(),
TextColumn::make('category.name')
->label(__('Category')),
ToggleColumn::make('open')
->label(__('Open')),
TextColumn::make('created_at')
->label(__('Created'))
->dateTime(),
];
}
#[\Override]
public static function getRelations(): array
{
return [
CategoriesRelationManager::class,
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListHelpQuestions::route('/'),
'create' => CreateHelpQuestion::route('/create'),
'view' => ViewHelpQuestion::route('/{record}'),
'edit' => EditHelpQuestion::route('/{record}/edit'),
];
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HelpQuestionResource\Pages;
use App\Filament\Resources\Atom\HelpQuestionResource;
use Filament\Resources\Pages\CreateRecord;
class CreateHelpQuestion extends CreateRecord
{
#[\Override]
protected static string $resource = HelpQuestionResource::class;
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HelpQuestionResource\Pages;
use App\Filament\Resources\Atom\HelpQuestionResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditHelpQuestion extends EditRecord
{
#[\Override]
protected static string $resource = HelpQuestionResource::class;
#[\Override]
protected function getActions(): array
{
return [
DeleteAction::make(),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HelpQuestionResource\Pages;
use App\Filament\Resources\Atom\HelpQuestionResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListHelpQuestions extends ListRecords
{
#[\Override]
protected static string $resource = HelpQuestionResource::class;
#[\Override]
protected function getActions(): array
{
return [
CreateAction::make(),
];
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HelpQuestionResource\Pages;
use App\Filament\Resources\Atom\HelpQuestionResource;
use Filament\Resources\Pages\ViewRecord;
class ViewHelpQuestion extends ViewRecord
{
#[\Override]
protected static string $resource = HelpQuestionResource::class;
}
@@ -0,0 +1,56 @@
<?php
namespace App\Filament\Resources\Atom\HelpQuestionResource\RelationManagers;
use App\Filament\Resources\Atom\HelpQuestionCategoryResource;
use App\Filament\Traits\TranslatableResource;
use Filament\Actions\AttachAction;
use Filament\Actions\CreateAction;
use Filament\Actions\DetachAction;
use Filament\Actions\DetachBulkAction;
use Filament\Actions\EditAction;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
class CategoriesRelationManager extends RelationManager
{
use TranslatableResource;
#[\Override]
protected static string $relationship = 'categories';
#[\Override]
protected static ?string $recordTitleAttribute = 'name';
public static string $translateIdentifier = 'help-question-categories';
#[\Override]
protected static ?string $inverseRelationship = 'questions';
#[\Override]
public function form(Schema $schema): Schema
{
return $schema->components(HelpQuestionCategoryResource::getForm());
}
public function table(Table $table): Table
{
return $table->columns(HelpQuestionCategoryResource::getTable())
->modifyQueryUsing(fn ($query) => $query->latest('id'))
->filters([
//
])
->headerActions([
CreateAction::make(),
AttachAction::make(),
])
->recordActions([
EditAction::make(),
DetachAction::make(),
])
->toolbarActions([
DetachBulkAction::make(),
]);
}
}
@@ -0,0 +1,125 @@
<?php
namespace App\Filament\Resources\Atom\HousekeepingPermissions;
use App\Filament\Resources\Atom\HousekeepingPermissions\Pages\ListHousekeepingPermissions;
use App\Models\WebsiteHousekeepingPermission;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class HousekeepingPermissionResource extends Resource
{
#[\Override]
protected static ?string $model = WebsiteHousekeepingPermission::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-shield-check';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'website/housekeeping-permissions';
#[\Override]
protected static ?string $navigationLabel = 'Housekeeping permissions';
public static string $translateIdentifier = 'housekeeping-permissions';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components([
Section::make()
->schema([
TextInput::make('permission')
->label(__('filament::resources.inputs.permission'))
->maxLength(50)
->autocomplete()
->unique(ignoreRecord: true)
->required(),
TextInput::make('min_rank')
->label(__('filament::resources.inputs.min_rank'))
->required()
->maxLength(255)
->autocomplete(),
TextInput::make('description')
->label(__('filament::resources.inputs.description'))
->nullable()
->maxLength(255)
->autocomplete()
->columnSpanFull(),
])
->columns([
'sm' => 2,
]),
]);
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->defaultSort('id', 'asc')
->columns([
TextColumn::make('permission')
->label(__('filament::resources.columns.permission'))
->searchable(),
TextColumn::make('min_rank')
->label(__('filament::resources.columns.min_rank'))
->searchable()
->limit(30),
TextColumn::make('description')
->label(__('filament::resources.columns.description'))
->toggleable()
->searchable()
->tooltip(function (TextColumn $column): ?string {
$state = $column->getState();
if (! is_string($state) || strlen($state) <= $column->getCharacterLimit()) {
return null;
}
return $state;
})
->limit(60),
])
->filters([
//
])
->recordActions([
EditAction::make(),
DeleteAction::make(),
])
->toolbarActions([
//
]);
}
#[\Override]
public static function getRelations(): array
{
return [
//
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListHousekeepingPermissions::route('/'),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\HousekeepingPermissions\Pages;
use App\Filament\Resources\Atom\HousekeepingPermissions\HousekeepingPermissionResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListHousekeepingPermissions extends ListRecords
{
#[\Override]
protected static string $resource = HousekeepingPermissionResource::class;
#[\Override]
protected function getHeaderActions(): array
{
return [
CreateAction::make(),
];
}
}
+119
View File
@@ -0,0 +1,119 @@
<?php
namespace App\Filament\Resources\Atom;
use App\Filament\Resources\Atom\NavigationResource\Pages\CreateNavigation;
use App\Filament\Resources\Atom\NavigationResource\Pages\EditNavigation;
use App\Filament\Resources\Atom\NavigationResource\Pages\ListNavigations;
use App\Filament\Resources\Atom\NavigationResource\RelationManagers\SubNavigationsRelationManager;
use App\Filament\Traits\TranslatableResource;
use App\Models\WebsiteNavigation;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class NavigationResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = WebsiteNavigation::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-bars-3';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'website/navigations';
public static string $translateIdentifier = 'navigations';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components(static::getForm());
}
public static function getForm(): array
{
return [
TextInput::make('name')
->label(__('Name'))
->required()
->maxLength(255),
TextInput::make('url')
->label(__('URL'))
->required()
->maxLength(255),
TextInput::make('icon')
->label(__('Icon'))
->maxLength(255),
TextInput::make('order')
->label(__('Order'))
->numeric()
->default(0),
Select::make('parent_id')
->label(__('Parent Navigation'))
->relationship('parent', 'name')
->nullable(),
];
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->columns(static::getTable());
}
public static function getTable(): array
{
return [
TextColumn::make('id')
->label(__('ID'))
->sortable(),
TextColumn::make('name')
->label(__('Name'))
->searchable(),
TextColumn::make('url')
->label(__('URL')),
TextColumn::make('order')
->label(__('Order'))
->sortable(),
TextColumn::make('parent.name')
->label(__('Parent')),
];
}
#[\Override]
public static function getRelations(): array
{
return [
SubNavigationsRelationManager::class,
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListNavigations::route('/'),
'create' => CreateNavigation::route('/create'),
'edit' => EditNavigation::route('/{record}/edit'),
];
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\NavigationResource\Pages;
use App\Filament\Resources\Atom\NavigationResource;
use Filament\Resources\Pages\CreateRecord;
class CreateNavigation extends CreateRecord
{
#[\Override]
protected static string $resource = NavigationResource::class;
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\NavigationResource\Pages;
use App\Filament\Resources\Atom\NavigationResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditNavigation extends EditRecord
{
#[\Override]
protected static string $resource = NavigationResource::class;
#[\Override]
protected function getActions(): array
{
return [
DeleteAction::make(),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\NavigationResource\Pages;
use App\Filament\Resources\Atom\NavigationResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListNavigations extends ListRecords
{
#[\Override]
protected static string $resource = NavigationResource::class;
#[\Override]
protected function getActions(): array
{
return [
CreateAction::make(),
];
}
}
@@ -0,0 +1,95 @@
<?php
namespace App\Filament\Resources\Atom\NavigationResource\RelationManagers;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\DissociateAction;
use Filament\Actions\DissociateBulkAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;
class SubNavigationsRelationManager extends RelationManager
{
#[\Override]
protected static string $relationship = 'subNavigations';
#[\Override]
protected static ?string $recordTitleAttribute = 'label';
#[\Override]
public function form(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('label')
->label(__('filament::resources.inputs.label'))
->columnSpanFull()
->required()
->maxLength(255),
TextInput::make('slug')
->label(__('filament::resources.inputs.slug')),
TextInput::make('order')
->numeric()
->minValue(0)
->default(0)
->label(__('filament::resources.columns.order')),
Toggle::make('visible')
->label(__('filament::resources.columns.visible')),
Toggle::make('new_tab')
->label(__('filament::resources.columns.new_tab')),
])
->columns([
'sm' => 2,
]);
}
public function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('label'),
TextColumn::make('slug')
->label(__('filament::resources.columns.slug')),
ToggleColumn::make('visible')
->label(__('filament::resources.columns.visible')),
ToggleColumn::make('new_tab')
->label(__('filament::resources.columns.new_tab')),
TextColumn::make('order')
->label(__('filament::resources.columns.order')),
])
->reorderable('order')
->filters([
//
])
->headerActions([
CreateAction::make(),
// Tables\Actions\AssociateAction::make(),
])
->recordActions([
EditAction::make(),
DissociateAction::make(),
DeleteAction::make(),
])
->toolbarActions([
DissociateBulkAction::make(),
DeleteBulkAction::make(),
]);
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Permissions\Pages;
use App\Filament\Resources\Atom\Permissions\PermissionResource;
use Filament\Resources\Pages\CreateRecord;
class CreatePermission extends CreateRecord
{
#[\Override]
protected static string $resource = PermissionResource::class;
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Permissions\Pages;
use App\Filament\Resources\Atom\Permissions\PermissionResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditPermission extends EditRecord
{
#[\Override]
protected static string $resource = PermissionResource::class;
#[\Override]
protected function getHeaderActions(): array
{
return [
DeleteAction::make(),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Permissions\Pages;
use App\Filament\Resources\Atom\Permissions\PermissionResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListPermissions extends ListRecords
{
#[\Override]
protected static string $resource = PermissionResource::class;
#[\Override]
protected function getHeaderActions(): array
{
return [
CreateAction::make(),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Permissions\Pages;
use App\Filament\Resources\Atom\Permissions\PermissionResource;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ViewRecord;
class ViewPermission extends ViewRecord
{
#[\Override]
protected static string $resource = PermissionResource::class;
#[\Override]
public function getHeaderActions(): array
{
return [
EditAction::make(),
];
}
}
@@ -0,0 +1,276 @@
<?php
namespace App\Filament\Resources\Atom\Permissions;
use App\Filament\Resources\Atom\Permissions\Pages\CreatePermission;
use App\Filament\Resources\Atom\Permissions\Pages\EditPermission;
use App\Filament\Resources\Atom\Permissions\Pages\ListPermissions;
use App\Filament\Resources\Atom\Permissions\Pages\ViewPermission;
use App\Filament\Tables\Columns\HabboBadgeColumn;
use App\Filament\Traits\TranslatableResource;
use App\Models\Game\Permission;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\ColorPicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\ToggleButtons;
use Filament\Pages\Enums\SubNavigationPosition;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;
// ensure Str is imported once
class PermissionResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = Permission::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-shield-check';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'website/permissions';
public static string $translateIdentifier = 'permissions';
#[\Override]
protected static ?string $recordTitleAttribute = 'rank_name';
#[\Override]
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
#[\Override]
public static function form(\Filament\Schemas\Schema $schema): \Filament\Schemas\Schema
{
/**
* @param string $name
* @param bool $needsSecondOption = false
*/
$groupedToggleButton = fn (string $name, bool $needsSecondOption = false): ToggleButtons => ToggleButtons::make($name)
->label(function () use ($name) {
$translationKey = "filament::resources.permissions.{$name}";
$translation = __($translationKey);
if ($translationKey == $translation) {
return $name;
}
return $translation;
})
->options(function () use ($needsSecondOption) {
$options = [
'0' => __('filament::resources.options.no'),
'1' => __('filament::resources.options.yes'),
];
if ($needsSecondOption) {
$options['2'] = __('filament::resources.options.rights');
}
return $options;
})
->icons(['0' => 'heroicon-o-check', '1' => 'heroicon-o-x-mark', '2' => 'heroicon-o-sparkles'])
->colors(['0' => 'danger', '1' => 'success'])
->grouped();
return $schema
->components([
Tabs::make('Main')
->tabs([
Tab::make(__('filament::resources.tabs.General Information'))
->schema([
TextInput::make('rank_name')
->label(__('filament::resources.inputs.name'))
->maxLength(25)
->required(),
TextInput::make('badge')
->label(__('filament::resources.inputs.badge_code'))
->maxLength(12)
->required(),
TextInput::make('level')
->label(__('filament::resources.inputs.level'))
->required(),
TextInput::make('room_effect')
->label(__('filament::resources.inputs.room_effect'))
->required(),
]),
Tab::make(__('filament::resources.tabs.In-game Permissions'))
->schema([
Section::make(__('filament::resources.sections.permissions.title'))
->description(new HtmlString(__('filament::resources.sections.permissions.description')))
->schema([
Grid::make()
->columns([
'sm' => 2,
'md' => 3,
'lg' => 3,
])
->schema(function () use ($groupedToggleButton) {
$columns = Schema::getColumns('permissions');
$arcturusPermissions = collect($columns)->filter(function (array $column) {
$columnName = $column['name'] ?? null;
if (! $columnName) {
return false;
}
return str_starts_with($columnName, 'cmd')
|| str_starts_with($columnName, 'acc')
|| str_ends_with($columnName, 'cmd');
})->values();
return $arcturusPermissions->map(function (array $column) use ($groupedToggleButton) {
$columnName = $column['name'];
$needsSecondOption = $column['type_name'] == 'enum' && str_ends_with((string) $column['type'], "'2')");
return $groupedToggleButton($columnName, $needsSecondOption);
})->toArray();
}),
]),
]),
Tab::make(__('filament::resources.tabs.Configurations'))
->schema([
Grid::make(['default' => 2])
->schema([
Select::make('log_commands')
->label(__('filament::resources.inputs.log_commands'))
->columnSpanFull()
->options([
'0' => __('filament::resources.options.no'),
'1' => __('filament::resources.options.yes'),
]),
TextInput::make('prefix')
->label(__('filament::resources.inputs.prefix'))
->maxLength(5)
->required(),
ColorPicker::make('prefix_color')
->label(__('filament::resources.inputs.prefix_color'))
->required(),
Toggle::make('hidden_rank')
->label(__('filament::resources.inputs.is_hidden'))
->columnSpanFull(),
Section::make()
->schema([
Grid::make()
->columns([
'md' => 2,
])
->schema([
TextInput::make('auto_credits_amount')
->columnSpan(1)
->label(__('filament::resources.inputs.auto_credits_amount'))
->required(),
TextInput::make('auto_pixels_amount')
->label(__('filament::resources.inputs.auto_pixels_amount'))
->required(),
TextInput::make('auto_gotw_amount')
->label(__('filament::resources.inputs.auto_gotw_amount'))
->required(),
TextInput::make('auto_points_amount')
->label(__('filament::resources.inputs.auto_points_amount'))
->required(),
]),
]),
]),
]),
])
->columnSpanFull()
->persistTabInQueryString(),
]);
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->defaultSort('id', 'desc')
->columns([
TextColumn::make('id')
->label(__('filament::resources.columns.id')),
HabboBadgeColumn::make('badge')
->alignCenter()
->label(__('filament::resources.columns.image')),
TextColumn::make('rank_name')
->label(__('filament::resources.columns.name'))
->description(fn (Permission $record) => Str::limit($record->description, 40))
->tooltip(function (Permission $record): ?string {
$description = $record->description;
if (strlen($description) <= 40) {
return null;
}
return $description;
})
->searchable(),
TextColumn::make('prefix')
->label(__('filament::resources.columns.prefix'))
->description(fn (Permission $record) => $record->prefix_color)
->searchable(),
ToggleColumn::make('hidden_rank')
->label(__('filament::resources.columns.is_hidden')),
])
->filters([
//
])
->recordActions([
ViewAction::make(),
EditAction::make(),
])
->toolbarActions([
]);
}
#[\Override]
public static function getRelations(): array
{
return [
//
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListPermissions::route('/'),
'create' => CreatePermission::route('/create'),
'view' => ViewPermission::route('/{record}'),
'edit' => EditPermission::route('/{record}/edit'),
];
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Tags\Pages;
use App\Filament\Resources\Atom\Tags\TagResource;
use Filament\Resources\Pages\CreateRecord;
class CreateTag extends CreateRecord
{
#[\Override]
protected static string $resource = TagResource::class;
}
+23
View File
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Tags\Pages;
use App\Filament\Resources\Atom\Tags\TagResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditTag extends EditRecord
{
#[\Override]
protected static string $resource = TagResource::class;
#[\Override]
protected function getActions(): array
{
return [
DeleteAction::make(),
];
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Tags\Pages;
use App\Filament\Resources\Atom\Tags\TagResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListTags extends ListRecords
{
#[\Override]
protected static string $resource = TagResource::class;
#[\Override]
protected function getActions(): array
{
return [
CreateAction::make(),
];
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Tags\Pages;
use App\Filament\Resources\Atom\Tags\TagResource;
use Filament\Resources\Pages\ViewRecord;
class ViewTag extends ViewRecord
{
#[\Override]
protected static string $resource = TagResource::class;
}
@@ -0,0 +1,55 @@
<?php
namespace App\Filament\Resources\Atom\Tags\RelationManagers;
use App\Filament\Resources\Atom\Articles\ArticleResource;
use App\Filament\Traits\TranslatableResource;
use Filament\Actions\AttachAction;
use Filament\Actions\DetachAction;
use Filament\Actions\DetachBulkAction;
use Filament\Actions\ViewAction;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
class ArticlesRelationManager extends RelationManager
{
use TranslatableResource;
// Use camelCase to match the method in the Tag model
#[\Override]
protected static string $relationship = 'websiteArticles';
#[\Override]
protected static ?string $recordTitleAttribute = 'title';
public static string $translateIdentifier = 'article';
#[\Override]
public function form(Schema $schema): Schema
{
return $schema
->components(ArticleResource::getForm());
}
public function table(Table $table): Table
{
return $table
->columns(ArticleResource::getTable())
->modifyQueryUsing(fn ($query) => $query->latest())
->filters([
//
])
->headerActions([
AttachAction::make()
->preloadRecordSelect(),
])
->recordActions([
ViewAction::make(),
DetachAction::make(),
])
->toolbarActions([
DetachBulkAction::make(),
]);
}
}
+130
View File
@@ -0,0 +1,130 @@
<?php
namespace App\Filament\Resources\Atom\Tags;
use App\Filament\Resources\Atom\Tags\Pages\CreateTag;
use App\Filament\Resources\Atom\Tags\Pages\EditTag;
use App\Filament\Resources\Atom\Tags\Pages\ListTags;
use App\Filament\Resources\Atom\Tags\Pages\ViewTag;
use App\Filament\Resources\Atom\Tags\RelationManagers\ArticlesRelationManager;
use App\Filament\Traits\TranslatableResource;
use App\Models\Articles\Tag;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\ColorPicker;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\ColorColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class TagResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = Tag::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-tag';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'website/tags';
public static string $translateIdentifier = 'tags';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components(static::getForm());
}
public static function getForm(): array
{
return [
Tabs::make('Main')
->tabs([
Tab::make(__('filament::resources.tabs.Home'))
->icon('heroicon-o-home')
->schema([
TextInput::make('name')
->label(__('filament::resources.inputs.name'))
->required()
->maxLength(255)
->autocomplete()
->columnSpan('full'),
ColorPicker::make('background_color')
->label(__('filament::resources.inputs.background_color'))
->required()
->columnSpan('full'),
]),
])->columnSpanFull(),
];
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->defaultSort('id', 'desc')
->columns(static::getTable())
->filters([
//
])
->recordActions([
ViewAction::make(),
EditAction::make(),
])
->toolbarActions([
DeleteBulkAction::make(),
]);
}
public static function getTable(): array
{
return [
TextColumn::make('id')
->label(__('filament::resources.columns.id')),
TextColumn::make('name')
->label(__('filament::resources.columns.name'))
->searchable()
->limit(50),
ColorColumn::make('background_color')
->label(__('filament::resources.columns.background_color'))
->searchable()
->copyable()
->copyMessage(__('filament::resources.common.Sucessfull'))
->copyMessageDuration(1500),
];
}
#[\Override]
public static function getRelations(): array
{
return [
ArticlesRelationManager::class,
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListTags::route('/'),
'create' => CreateTag::route('/create'),
'view' => ViewTag::route('/{record}'),
'edit' => EditTag::route('/{record}/edit'),
];
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Teams\Pages;
use App\Filament\Resources\Atom\Teams\TeamResource;
use Filament\Resources\Pages\CreateRecord;
class CreateTeam extends CreateRecord
{
#[\Override]
protected static string $resource = TeamResource::class;
}
+23
View File
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Teams\Pages;
use App\Filament\Resources\Atom\Teams\TeamResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditTeam extends EditRecord
{
#[\Override]
protected static string $resource = TeamResource::class;
#[\Override]
protected function getActions(): array
{
return [
DeleteAction::make(),
];
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\Teams\Pages;
use App\Filament\Resources\Atom\Teams\TeamResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListTeams extends ListRecords
{
#[\Override]
protected static string $resource = TeamResource::class;
#[\Override]
protected function getActions(): array
{
return [
CreateAction::make(),
];
}
}
+122
View File
@@ -0,0 +1,122 @@
<?php
namespace App\Filament\Resources\Atom\Teams;
use App\Filament\Resources\Atom\Teams\Pages\CreateTeam;
use App\Filament\Resources\Atom\Teams\Pages\EditTeam;
use App\Filament\Resources\Atom\Teams\Pages\ListTeams;
use App\Filament\Tables\Columns\HabboBadgeColumn;
use App\Filament\Traits\TranslatableResource;
use App\Models\Community\Staff\WebsiteTeam;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class TeamResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = WebsiteTeam::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-user-group';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'website/teams';
public static string $translateIdentifier = 'teams';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components([
Section::make()
->schema([
TextInput::make('rank_name')
->autofocus()
->maxLength(255)
->required()
->label(__('filament::resources.inputs.name')),
TextInput::make('job_description')
->maxLength(255)
->label(__('filament::resources.inputs.description')),
TextInput::make('badge')
->maxLength(255)
->label(__('filament::resources.inputs.badge_code'))
->required(),
Toggle::make('hidden_rank')
->label(__('filament::resources.inputs.is_hidden')),
]),
]);
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->defaultSort('id', 'desc')
->columns([
TextColumn::make('id')
->label(__('filament::resources.columns.id')),
HabboBadgeColumn::make('badge')
->label(__('filament::resources.columns.badge')),
TextColumn::make('rank_name')
->label(__('filament::resources.columns.name')),
TextColumn::make('job_description')
->label(__('filament::resources.inputs.description')),
IconColumn::make('hidden_rank')
->label(__('filament::resources.columns.is_hidden'))
->icon(fn (WebsiteTeam $record) => $record->hidden_rank ? 'heroicon-o-check-circle' : 'heroicon-o-x-circle')
->colors([
'danger' => false,
'success' => true,
]),
])
->filters([
//
])
->recordActions([
EditAction::make(),
])
->toolbarActions([
DeleteBulkAction::make(),
]);
}
#[\Override]
public static function getRelations(): array
{
return [
//
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListTeams::route('/'),
'create' => CreateTeam::route('/create'),
'edit' => EditTeam::route('/{record}/edit'),
];
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\WebsiteDrawBadges\Pages;
use App\Filament\Resources\Atom\WebsiteDrawBadges\WebsiteDrawBadgeResource;
use Filament\Resources\Pages\EditRecord;
class EditWebsiteDrawBadge extends EditRecord
{
#[\Override]
protected static string $resource = WebsiteDrawBadgeResource::class;
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\WebsiteDrawBadges\Pages;
use App\Filament\Resources\Atom\WebsiteDrawBadges\WebsiteDrawBadgeResource;
use Filament\Resources\Pages\ListRecords;
class ListWebsiteDrawBadge extends ListRecords
{
#[\Override]
protected static string $resource = WebsiteDrawBadgeResource::class;
}
@@ -0,0 +1,184 @@
<?php
namespace App\Filament\Resources\Atom\WebsiteDrawBadges;
use App\Filament\Resources\Atom\WebsiteDrawBadges\Pages\EditWebsiteDrawBadge;
use App\Filament\Resources\Atom\WebsiteDrawBadges\Pages\ListWebsiteDrawBadge;
use App\Models\WebsiteDrawBadge;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;
use Illuminate\Support\Facades\DB;
class WebsiteDrawBadgeResource extends Resource
{
#[\Override]
protected static ?string $model = WebsiteDrawBadge::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-trophy';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'draw-badges';
#[\Override]
protected static ?string $pluralModelLabel = 'draw badges';
#[\Override]
protected static ?string $navigationLabel = 'Draw Badges';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('badge_name')
->label(__('Badge Name'))
->nullable()
->maxLength(24)
->autocomplete(false),
TextInput::make('badge_desc')
->label(__('Badge Description'))
->nullable()
->maxLength(255)
->autocomplete(false)
->columnSpanFull(),
Toggle::make('published')
->label(__('Published'))
->default(false),
]);
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->defaultSort('id', 'desc')
->columns([
TextColumn::make('id')
->label(__('ID'))
->sortable(),
TextColumn::make('user_id')
->label(__('User ID')),
TextColumn::make('user.username')
->label(__('Username'))
->sortable()
->searchable(),
TextColumn::make('badge_name')
->limit(8)
->label(__('Badge Name')),
TextColumn::make('badge_desc')
->label(__('Badge description'))
->limit(35)
->tooltip(function (TextColumn $column): ?string {
$state = $column->getState();
if (strlen($state) <= $column->getCharacterLimit()) {
return null;
}
return $state;
}),
TextColumn::make('created_at')
->label(__('Created At'))
->dateTime(),
ImageColumn::make('badge_url')
->label(__('Badge'))
->getStateUsing(fn ($record) => config('app.url') . $record->badge_url)
->extraAttributes(['style' => 'image-rendering: pixelated'])
->size(40),
ToggleColumn::make('published')
->label(__('Published')),
])
->recordActions([
DeleteAction::make()
->before(function (DeleteAction $action, WebsiteDrawBadge $record) {
$badgeCode = pathinfo($record->badge_path, PATHINFO_FILENAME);
// Remove the badge from any user before deleting it.
if ($record->published) {
DB::table('users_badges')
->where('user_id', $record->user_id)
->where('badge_code', $badgeCode)
->delete();
}
// Remove from JSON
$filePath = DB::table('website_settings')->where('key', 'nitro_external_texts_file')->value('value');
if ($filePath && file_exists($filePath) && is_writable($filePath)) {
$json = json_decode(file_get_contents($filePath), true);
unset($json["badge_name_{$badgeCode}"]);
unset($json["badge_desc_{$badgeCode}"]);
file_put_contents($filePath, json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
// Delete the badge file from the filesystem
$badgePath = $record->badge_path;
if ($badgePath && file_exists($badgePath)) {
unlink($badgePath);
}
}),
])
->toolbarActions([
DeleteBulkAction::make()
->before(function (DeleteBulkAction $action, $records) {
foreach ($records as $record) {
$badgeCode = pathinfo((string) $record->badge_path, PATHINFO_FILENAME);
// Remove the badge from any user before deleting it.
if ($record->published) {
DB::table('users_badges')
->where('user_id', $record->user_id)
->where('badge_code', $badgeCode)
->delete();
}
$filePath = DB::table('website_settings')->where('key', 'nitro_external_texts_file')->value('value');
if ($filePath && file_exists($filePath) && is_writable($filePath)) {
$json = json_decode(file_get_contents($filePath), true);
unset($json["badge_name_{$badgeCode}"]);
unset($json["badge_desc_{$badgeCode}"]);
file_put_contents($filePath, json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
$badgePath = $record->badge_path;
if ($badgePath && file_exists($badgePath)) {
unlink($badgePath);
}
}
}),
]);
}
#[\Override]
public static function getRelations(): array
{
return [];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ListWebsiteDrawBadge::route('/'),
'edit' => EditWebsiteDrawBadge::route('/{record}/edit'),
];
}
#[\Override]
public static function canCreate(): bool
{
return false;
}
}
+94
View File
@@ -0,0 +1,94 @@
<?php
namespace App\Filament\Resources\Atom;
use App\Filament\Resources\Atom\WriteableBoxResource\Pages\ManageWriteableBoxes;
use App\Filament\Traits\TranslatableResource;
use App\Models\WebsiteWriteableBox;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class WriteableBoxResource extends Resource
{
use TranslatableResource;
#[\Override]
protected static ?string $model = WebsiteWriteableBox::class;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-pencil-square';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Website';
#[\Override]
protected static ?string $slug = 'website/writeable-boxes';
public static string $translateIdentifier = 'writeable-boxes';
#[\Override]
public static function form(Schema $schema): Schema
{
return $schema
->components(static::getForm());
}
public static function getForm(): array
{
return [
TextInput::make('title')
->label(__('Title'))
->required()
->maxLength(255),
Textarea::make('content')
->label(__('Content'))
->required(),
TextInput::make('order')
->label(__('Order'))
->numeric()
->default(0),
];
}
#[\Override]
public static function table(Table $table): Table
{
return $table
->columns(static::getTable());
}
public static function getTable(): array
{
return [
TextColumn::make('id')
->label(__('ID'))
->sortable(),
TextColumn::make('title')
->label(__('Title'))
->searchable(),
TextColumn::make('order')
->label(__('Order'))
->sortable(),
TextColumn::make('created_at')
->label(__('Created'))
->dateTime(),
];
}
#[\Override]
public static function getPages(): array
{
return [
'index' => ManageWriteableBoxes::route('/'),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Atom\WriteableBoxResource\Pages;
use App\Filament\Resources\Atom\WriteableBoxResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ManageRecords;
class ManageWriteableBoxes extends ManageRecords
{
#[\Override]
protected static string $resource = WriteableBoxResource::class;
#[\Override]
protected function getActions(): array
{
return [
CreateAction::make(),
];
}
}