Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Achievements;
|
||||
|
||||
use App\Filament\Resources\Achievements\Pages\CreateAchievement;
|
||||
use App\Filament\Resources\Achievements\Pages\EditAchievement;
|
||||
use App\Filament\Resources\Achievements\Pages\ListAchievements;
|
||||
use App\Filament\Resources\Achievements\Schemas\AchievementForm;
|
||||
use App\Filament\Resources\Achievements\Tables\AchievementsTable;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Streaks\Models\Achievement;
|
||||
|
||||
class AchievementResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Achievement::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return AchievementForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return AchievementsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListAchievements::route('/'),
|
||||
'create' => CreateAchievement::route('/create'),
|
||||
'edit' => EditAchievement::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Achievements\Pages;
|
||||
|
||||
use App\Filament\Resources\Achievements\AchievementResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateAchievement extends CreateRecord
|
||||
{
|
||||
protected static string $resource = AchievementResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Achievements\Pages;
|
||||
|
||||
use App\Filament\Resources\Achievements\AchievementResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditAchievement extends EditRecord
|
||||
{
|
||||
protected static string $resource = AchievementResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Achievements\Pages;
|
||||
|
||||
use App\Filament\Resources\Achievements\AchievementResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListAchievements extends ListRecords
|
||||
{
|
||||
protected static string $resource = AchievementResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Achievements\Schemas;
|
||||
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class AchievementForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('user_id')
|
||||
->relationship('user', 'name')
|
||||
->required(),
|
||||
TextInput::make('key')
|
||||
->required(),
|
||||
DateTimePicker::make('earned_at')
|
||||
->required(),
|
||||
TextInput::make('meta'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Achievements\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
/**
|
||||
* Table des badges débloqués : utilisateur, clé du badge, date d'obtention.
|
||||
*/
|
||||
class AchievementsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('user.name')
|
||||
->label('Utilisateur')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('key')
|
||||
->label('Badge')
|
||||
->badge()
|
||||
->searchable(),
|
||||
TextColumn::make('earned_at')
|
||||
->label('Obtenu le')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->defaultSort('earned_at', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Exercises;
|
||||
|
||||
use App\Filament\Resources\Exercises\Pages\ListExercises;
|
||||
use App\Filament\Resources\Exercises\Schemas\ExerciseInfolist;
|
||||
use App\Filament\Resources\Exercises\Tables\ExercisesTable;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Exercises\Models\Exercise;
|
||||
use UnitEnum;
|
||||
|
||||
/**
|
||||
* Catalogue d'exercices — consultation en lecture seule (1324 lignes).
|
||||
* Filtrable par body_part / equipment / target, recherche sur le nom.
|
||||
*/
|
||||
class ExerciseResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Exercise::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
protected static string|UnitEnum|null $navigationGroup = 'Catalogue';
|
||||
|
||||
protected static ?string $modelLabel = 'exercice';
|
||||
|
||||
protected static ?string $pluralModelLabel = 'exercices';
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'name';
|
||||
|
||||
public static function infolist(Schema $schema): Schema
|
||||
{
|
||||
return ExerciseInfolist::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return ExercisesTable::configure($table);
|
||||
}
|
||||
|
||||
// Catalogue en lecture seule : pas de création / édition / suppression.
|
||||
public static function canCreate(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListExercises::route('/'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Exercises\Pages;
|
||||
|
||||
use App\Filament\Resources\Exercises\ExerciseResource;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListExercises extends ListRecords
|
||||
{
|
||||
protected static string $resource = ExerciseResource::class;
|
||||
|
||||
// Catalogue en lecture seule : aucune action de création.
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Exercises\Schemas;
|
||||
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
/**
|
||||
* Fiche de consultation d'un exercice (modal "Voir").
|
||||
* Affiche les métadonnées et les instructions du dataset (lecture seule).
|
||||
*/
|
||||
class ExerciseInfolist
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
ImageEntry::make('image_url')
|
||||
->label('Aperçu')
|
||||
->height(160)
|
||||
->square(),
|
||||
TextEntry::make('name')
|
||||
->label('Nom'),
|
||||
TextEntry::make('category')
|
||||
->label('Catégorie')
|
||||
->badge(),
|
||||
TextEntry::make('body_part')
|
||||
->label('Partie du corps')
|
||||
->badge(),
|
||||
TextEntry::make('equipment')
|
||||
->label('Équipement')
|
||||
->badge(),
|
||||
TextEntry::make('target')
|
||||
->label('Muscle cible')
|
||||
->badge(),
|
||||
TextEntry::make('muscle_group')
|
||||
->label('Groupe musculaire'),
|
||||
TextEntry::make('external_id')
|
||||
->label('Identifiant externe'),
|
||||
TextEntry::make('attribution')
|
||||
->label('Attribution')
|
||||
->placeholder('—'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Exercises\Tables;
|
||||
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Exercises\Models\Exercise;
|
||||
|
||||
/**
|
||||
* Table du catalogue d'exercices : thumbnail + métadonnées, filtrable et consultable.
|
||||
*/
|
||||
class ExercisesTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
ImageColumn::make('image_url')
|
||||
->label('Aperçu')
|
||||
->square(),
|
||||
TextColumn::make('name')
|
||||
->label('Nom')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('body_part')
|
||||
->label('Partie du corps')
|
||||
->badge()
|
||||
->sortable(),
|
||||
TextColumn::make('equipment')
|
||||
->label('Équipement')
|
||||
->badge(),
|
||||
TextColumn::make('target')
|
||||
->label('Muscle cible')
|
||||
->badge(),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('body_part')
|
||||
->label('Partie du corps')
|
||||
->options(fn (): array => self::distinctOptions('body_part')),
|
||||
SelectFilter::make('equipment')
|
||||
->label('Équipement')
|
||||
->options(fn (): array => self::distinctOptions('equipment')),
|
||||
SelectFilter::make('target')
|
||||
->label('Muscle cible')
|
||||
->options(fn (): array => self::distinctOptions('target')),
|
||||
])
|
||||
->recordActions([
|
||||
ViewAction::make(),
|
||||
])
|
||||
->defaultSort('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Valeurs distinctes d'une colonne pour alimenter un filtre (clé = valeur = libellé brut).
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private static function distinctOptions(string $column): array
|
||||
{
|
||||
return Exercise::query()
|
||||
->whereNotNull($column)
|
||||
->distinct()
|
||||
->orderBy($column)
|
||||
->pluck($column, $column)
|
||||
->all();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Integrations;
|
||||
|
||||
use App\Filament\Resources\Integrations\Pages\CreateIntegration;
|
||||
use App\Filament\Resources\Integrations\Pages\EditIntegration;
|
||||
use App\Filament\Resources\Integrations\Pages\ListIntegrations;
|
||||
use App\Filament\Resources\Integrations\Schemas\IntegrationForm;
|
||||
use App\Filament\Resources\Integrations\Tables\IntegrationsTable;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Technical\Integrations\Models\Integration;
|
||||
|
||||
class IntegrationResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Integration::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return IntegrationForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return IntegrationsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListIntegrations::route('/'),
|
||||
'create' => CreateIntegration::route('/create'),
|
||||
'edit' => EditIntegration::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Integrations\Pages;
|
||||
|
||||
use App\Filament\Resources\Integrations\IntegrationResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateIntegration extends CreateRecord
|
||||
{
|
||||
protected static string $resource = IntegrationResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Integrations\Pages;
|
||||
|
||||
use App\Filament\Resources\Integrations\IntegrationResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditIntegration extends EditRecord
|
||||
{
|
||||
protected static string $resource = IntegrationResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Integrations\Pages;
|
||||
|
||||
use App\Filament\Resources\Integrations\IntegrationResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListIntegrations extends ListRecords
|
||||
{
|
||||
protected static string $resource = IntegrationResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Integrations\Schemas;
|
||||
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
use Technical\Integrations\Enums\IntegrationStatus;
|
||||
|
||||
class IntegrationForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('user_id')
|
||||
->relationship('user', 'name')
|
||||
->required(),
|
||||
TextInput::make('provider')
|
||||
->required(),
|
||||
TextInput::make('external_user_id'),
|
||||
DateTimePicker::make('token_expires_at'),
|
||||
TextInput::make('scopes'),
|
||||
Select::make('status')
|
||||
->options(IntegrationStatus::class)
|
||||
->default('connected')
|
||||
->required(),
|
||||
DateTimePicker::make('connected_at')
|
||||
->required(),
|
||||
DateTimePicker::make('last_synced_at'),
|
||||
TextInput::make('meta'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Integrations\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Technical\Integrations\Enums\IntegrationStatus;
|
||||
|
||||
/**
|
||||
* Table des intégrations externes : utilisateur, fournisseur, état, dernière synchro.
|
||||
* Les tokens (access/refresh) ne sont JAMAIS affichés.
|
||||
*/
|
||||
class IntegrationsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('user.name')
|
||||
->label('Utilisateur')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('provider')
|
||||
->label('Fournisseur')
|
||||
->badge()
|
||||
->searchable(),
|
||||
TextColumn::make('status')
|
||||
->label('État')
|
||||
->badge()
|
||||
->color(fn (IntegrationStatus $state): string => match ($state) {
|
||||
IntegrationStatus::Connected => 'success',
|
||||
IntegrationStatus::Revoked => 'gray',
|
||||
IntegrationStatus::Error => 'danger',
|
||||
}),
|
||||
TextColumn::make('last_synced_at')
|
||||
->label('Dernière synchro')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->placeholder('Jamais'),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('status')
|
||||
->label('État')
|
||||
->options(IntegrationStatus::class),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->defaultSort('last_synced_at', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Programs\Pages;
|
||||
|
||||
use App\Filament\Resources\Programs\ProgramResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateProgram extends CreateRecord
|
||||
{
|
||||
protected static string $resource = ProgramResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Programs\Pages;
|
||||
|
||||
use App\Filament\Resources\Programs\ProgramResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditProgram extends EditRecord
|
||||
{
|
||||
protected static string $resource = ProgramResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Programs\Pages;
|
||||
|
||||
use App\Filament\Resources\Programs\ProgramResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListPrograms extends ListRecords
|
||||
{
|
||||
protected static string $resource = ProgramResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Programs;
|
||||
|
||||
use App\Filament\Resources\Programs\Pages\CreateProgram;
|
||||
use App\Filament\Resources\Programs\Pages\EditProgram;
|
||||
use App\Filament\Resources\Programs\Pages\ListPrograms;
|
||||
use App\Filament\Resources\Programs\Schemas\ProgramForm;
|
||||
use App\Filament\Resources\Programs\Tables\ProgramsTable;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Programs\Models\Program;
|
||||
|
||||
class ProgramResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Program::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return ProgramForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return ProgramsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListPrograms::route('/'),
|
||||
'create' => CreateProgram::route('/create'),
|
||||
'edit' => EditProgram::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Programs\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class ProgramForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('user_id')
|
||||
->relationship('user', 'name')
|
||||
->required(),
|
||||
TextInput::make('name')
|
||||
->required(),
|
||||
TextInput::make('slug')
|
||||
->required(),
|
||||
Textarea::make('description')
|
||||
->columnSpanFull(),
|
||||
TextInput::make('duration_weeks')
|
||||
->required()
|
||||
->numeric(),
|
||||
TextInput::make('days_per_week')
|
||||
->numeric(),
|
||||
Toggle::make('is_public')
|
||||
->required(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Programs\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
/**
|
||||
* Table des programmes : nom, propriétaire, durée, visibilité, date de création.
|
||||
*/
|
||||
class ProgramsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->label('Nom')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('user.name')
|
||||
->label('Utilisateur')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('duration_weeks')
|
||||
->label('Semaines')
|
||||
->numeric()
|
||||
->sortable(),
|
||||
IconColumn::make('is_public')
|
||||
->label('Public')
|
||||
->boolean(),
|
||||
TextColumn::make('created_at')
|
||||
->label('Créé le')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Routines\Pages;
|
||||
|
||||
use App\Filament\Resources\Routines\RoutineResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateRoutine extends CreateRecord
|
||||
{
|
||||
protected static string $resource = RoutineResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Routines\Pages;
|
||||
|
||||
use App\Filament\Resources\Routines\RoutineResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditRoutine extends EditRecord
|
||||
{
|
||||
protected static string $resource = RoutineResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Routines\Pages;
|
||||
|
||||
use App\Filament\Resources\Routines\RoutineResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListRoutines extends ListRecords
|
||||
{
|
||||
protected static string $resource = RoutineResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Routines;
|
||||
|
||||
use App\Filament\Resources\Routines\Pages\CreateRoutine;
|
||||
use App\Filament\Resources\Routines\Pages\EditRoutine;
|
||||
use App\Filament\Resources\Routines\Pages\ListRoutines;
|
||||
use App\Filament\Resources\Routines\Schemas\RoutineForm;
|
||||
use App\Filament\Resources\Routines\Tables\RoutinesTable;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Routines\Models\Routine;
|
||||
|
||||
class RoutineResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Routine::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return RoutineForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return RoutinesTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListRoutines::route('/'),
|
||||
'create' => CreateRoutine::route('/create'),
|
||||
'edit' => EditRoutine::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Routines\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class RoutineForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('user_id')
|
||||
->relationship('user', 'name')
|
||||
->required(),
|
||||
TextInput::make('name')
|
||||
->required(),
|
||||
TextInput::make('slug')
|
||||
->required(),
|
||||
Textarea::make('description')
|
||||
->columnSpanFull(),
|
||||
Toggle::make('is_public')
|
||||
->required(),
|
||||
TextInput::make('estimated_minutes')
|
||||
->numeric(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Routines\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
/**
|
||||
* Table des routines : nom, propriétaire, visibilité, date de création.
|
||||
*/
|
||||
class RoutinesTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->label('Nom')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('user.name')
|
||||
->label('Utilisateur')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
IconColumn::make('is_public')
|
||||
->label('Publique')
|
||||
->boolean(),
|
||||
TextColumn::make('created_at')
|
||||
->label('Créée le')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Streaks\Pages;
|
||||
|
||||
use App\Filament\Resources\Streaks\StreakResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateStreak extends CreateRecord
|
||||
{
|
||||
protected static string $resource = StreakResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Streaks\Pages;
|
||||
|
||||
use App\Filament\Resources\Streaks\StreakResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditStreak extends EditRecord
|
||||
{
|
||||
protected static string $resource = StreakResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Streaks\Pages;
|
||||
|
||||
use App\Filament\Resources\Streaks\StreakResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListStreaks extends ListRecords
|
||||
{
|
||||
protected static string $resource = StreakResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Streaks\Schemas;
|
||||
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class StreakForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('user_id')
|
||||
->relationship('user', 'name')
|
||||
->required(),
|
||||
TextInput::make('current_count')
|
||||
->required()
|
||||
->numeric()
|
||||
->default(0),
|
||||
TextInput::make('longest_count')
|
||||
->required()
|
||||
->numeric()
|
||||
->default(0),
|
||||
DatePicker::make('last_active_date'),
|
||||
TextInput::make('freezes_available')
|
||||
->required()
|
||||
->numeric()
|
||||
->default(0),
|
||||
DatePicker::make('freeze_last_granted_on'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Streaks;
|
||||
|
||||
use App\Filament\Resources\Streaks\Pages\CreateStreak;
|
||||
use App\Filament\Resources\Streaks\Pages\EditStreak;
|
||||
use App\Filament\Resources\Streaks\Pages\ListStreaks;
|
||||
use App\Filament\Resources\Streaks\Schemas\StreakForm;
|
||||
use App\Filament\Resources\Streaks\Tables\StreaksTable;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Streaks\Models\Streak;
|
||||
|
||||
class StreakResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Streak::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return StreakForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return StreaksTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListStreaks::route('/'),
|
||||
'create' => CreateStreak::route('/create'),
|
||||
'edit' => EditStreak::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Streaks\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
/**
|
||||
* Table des streaks : régularité par utilisateur (courant, record, freezes, dernière activité).
|
||||
*/
|
||||
class StreaksTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('user.name')
|
||||
->label('Utilisateur')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('current_count')
|
||||
->label('Streak courant')
|
||||
->badge()
|
||||
->color('warning')
|
||||
->sortable(),
|
||||
TextColumn::make('longest_count')
|
||||
->label('Record')
|
||||
->numeric()
|
||||
->sortable(),
|
||||
TextColumn::make('freezes_available')
|
||||
->label('Freezes dispo')
|
||||
->numeric()
|
||||
->sortable(),
|
||||
TextColumn::make('last_active_date')
|
||||
->label('Dernière activité')
|
||||
->date()
|
||||
->sortable(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->defaultSort('current_count', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateUser extends CreateRecord
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditUser extends EditRecord
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListUsers extends ListRecords
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Schemas;
|
||||
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
use Functional\Users\Enums\Units;
|
||||
|
||||
class UserForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->required(),
|
||||
TextInput::make('email')
|
||||
->label('Email address')
|
||||
->email()
|
||||
->required(),
|
||||
DateTimePicker::make('email_verified_at'),
|
||||
TextInput::make('password')
|
||||
->password()
|
||||
->required(),
|
||||
TextInput::make('locale')
|
||||
->required()
|
||||
->default('fr'),
|
||||
Select::make('units')
|
||||
->options(Units::class)
|
||||
->default('metric')
|
||||
->required(),
|
||||
TextInput::make('timezone'),
|
||||
TextInput::make('avatar_path'),
|
||||
TextInput::make('oidc_sub'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
/**
|
||||
* Table des utilisateurs : identité, préférences d'affichage, date d'inscription.
|
||||
*/
|
||||
class UsersTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->label('Nom')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('email')
|
||||
->label('Email')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('locale')
|
||||
->label('Langue')
|
||||
->badge(),
|
||||
TextColumn::make('units')
|
||||
->label('Unités')
|
||||
->badge(),
|
||||
TextColumn::make('created_at')
|
||||
->label('Inscrit le')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users;
|
||||
|
||||
use App\Filament\Resources\Users\Pages\CreateUser;
|
||||
use App\Filament\Resources\Users\Pages\EditUser;
|
||||
use App\Filament\Resources\Users\Pages\ListUsers;
|
||||
use App\Filament\Resources\Users\Schemas\UserForm;
|
||||
use App\Filament\Resources\Users\Tables\UsersTable;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Users\Models\User;
|
||||
|
||||
class UserResource extends Resource
|
||||
{
|
||||
protected static ?string $model = User::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return UserForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return UsersTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListUsers::route('/'),
|
||||
'create' => CreateUser::route('/create'),
|
||||
'edit' => EditUser::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkoutSessions\Pages;
|
||||
|
||||
use App\Filament\Resources\WorkoutSessions\WorkoutSessionResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateWorkoutSession extends CreateRecord
|
||||
{
|
||||
protected static string $resource = WorkoutSessionResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkoutSessions\Pages;
|
||||
|
||||
use App\Filament\Resources\WorkoutSessions\WorkoutSessionResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditWorkoutSession extends EditRecord
|
||||
{
|
||||
protected static string $resource = WorkoutSessionResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkoutSessions\Pages;
|
||||
|
||||
use App\Filament\Resources\WorkoutSessions\WorkoutSessionResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListWorkoutSessions extends ListRecords
|
||||
{
|
||||
protected static string $resource = WorkoutSessionResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkoutSessions\Schemas;
|
||||
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Schemas\Schema;
|
||||
use Functional\Tracking\Enums\WorkoutSessionStatus;
|
||||
|
||||
class WorkoutSessionForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('user_id')
|
||||
->relationship('user', 'name')
|
||||
->required(),
|
||||
Select::make('routine_id')
|
||||
->relationship('routine', 'name'),
|
||||
Select::make('program_id')
|
||||
->relationship('program', 'name'),
|
||||
TextInput::make('title'),
|
||||
DateTimePicker::make('started_at')
|
||||
->required(),
|
||||
DateTimePicker::make('ended_at'),
|
||||
Select::make('status')
|
||||
->options(WorkoutSessionStatus::class)
|
||||
->default('active')
|
||||
->required(),
|
||||
Textarea::make('notes')
|
||||
->columnSpanFull(),
|
||||
TextInput::make('total_volume')
|
||||
->numeric(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkoutSessions\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Tracking\Enums\WorkoutSessionStatus;
|
||||
|
||||
/**
|
||||
* Table des séances : utilisateur, statut, début, volume total.
|
||||
*/
|
||||
class WorkoutSessionsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('user.name')
|
||||
->label('Utilisateur')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('status')
|
||||
->label('Statut')
|
||||
->badge()
|
||||
->color(fn (WorkoutSessionStatus $state): string => match ($state) {
|
||||
WorkoutSessionStatus::Active => 'warning',
|
||||
WorkoutSessionStatus::Completed => 'success',
|
||||
WorkoutSessionStatus::Abandoned => 'danger',
|
||||
}),
|
||||
TextColumn::make('started_at')
|
||||
->label('Débutée le')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
TextColumn::make('total_volume')
|
||||
->label('Volume total')
|
||||
->numeric()
|
||||
->sortable(),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('status')
|
||||
->label('Statut')
|
||||
->options(WorkoutSessionStatus::class),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->defaultSort('started_at', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkoutSessions;
|
||||
|
||||
use App\Filament\Resources\WorkoutSessions\Pages\CreateWorkoutSession;
|
||||
use App\Filament\Resources\WorkoutSessions\Pages\EditWorkoutSession;
|
||||
use App\Filament\Resources\WorkoutSessions\Pages\ListWorkoutSessions;
|
||||
use App\Filament\Resources\WorkoutSessions\Schemas\WorkoutSessionForm;
|
||||
use App\Filament\Resources\WorkoutSessions\Tables\WorkoutSessionsTable;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Functional\Tracking\Models\WorkoutSession;
|
||||
|
||||
class WorkoutSessionResource extends Resource
|
||||
{
|
||||
protected static ?string $model = WorkoutSession::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return WorkoutSessionForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return WorkoutSessionsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListWorkoutSessions::route('/'),
|
||||
'create' => CreateWorkoutSession::route('/create'),
|
||||
'edit' => EditWorkoutSession::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use Filament\Widgets\StatsOverviewWidget;
|
||||
use Filament\Widgets\StatsOverviewWidget\Stat;
|
||||
use Functional\Exercises\Models\Exercise;
|
||||
use Functional\Streaks\Models\Streak;
|
||||
use Functional\Tracking\Models\WorkoutSession;
|
||||
use Functional\Users\Models\User;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
/**
|
||||
* Vue d'ensemble du dashboard : chiffres clés de StreakFit.
|
||||
* Nb d'utilisateurs, séances (total + cette semaine), plus long streak en cours, catalogue d'exos.
|
||||
*/
|
||||
class StreakFitStatsOverview extends StatsOverviewWidget
|
||||
{
|
||||
protected function getStats(): array
|
||||
{
|
||||
$sessionsThisWeek = WorkoutSession::query()
|
||||
->where('started_at', '>=', Carbon::now()->startOfWeek())
|
||||
->count();
|
||||
|
||||
return [
|
||||
Stat::make('Utilisateurs', (string) User::query()->count())
|
||||
->description('Comptes inscrits')
|
||||
->descriptionIcon('heroicon-m-users')
|
||||
->color('primary'),
|
||||
|
||||
Stat::make('Séances', (string) WorkoutSession::query()->count())
|
||||
->description($sessionsThisWeek . ' cette semaine')
|
||||
->descriptionIcon('heroicon-m-fire')
|
||||
->color('warning'),
|
||||
|
||||
Stat::make('Meilleur streak en cours', (string) (Streak::query()->max('current_count') ?? 0))
|
||||
->description('Jours consécutifs')
|
||||
->descriptionIcon('heroicon-m-bolt')
|
||||
->color('success'),
|
||||
|
||||
Stat::make('Exercices', (string) Exercise::query()->count())
|
||||
->description('Catalogue disponible')
|
||||
->descriptionIcon('heroicon-m-rectangle-stack')
|
||||
->color('primary'),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user