diff --git a/app/Filament/Resources/ProjectResource.php b/app/Filament/Resources/ProjectResource.php index a08ee9ae..62ef2750 100644 --- a/app/Filament/Resources/ProjectResource.php +++ b/app/Filament/Resources/ProjectResource.php @@ -13,12 +13,15 @@ use Filament\Forms; use Filament\Forms\Components\DatePicker; use Filament\Forms\Components\Grid; +use Filament\Forms\Components\Select; use Filament\Forms\Components\SpatieMediaLibraryFileUpload; +use Filament\Forms\Components\TextInput; use Filament\Resources\Form; use Filament\Resources\Resource; use Filament\Resources\Table; use Filament\Tables; use Filament\Tables\Actions\Position; +use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\Filter; use Filament\Tables\Filters\SelectFilter; @@ -41,25 +44,38 @@ public static function form(Form $form): Form { return $form ->schema([ - Forms\Components\Select::make('organization_id') + Select::make('organization_id') ->label(__('project.labels.organization')) ->inlineLabel() ->columnSpanFull() ->relationship('organization', 'name') ->disabled() ->required(), - Forms\Components\Select::make('status')->options(ProjectStatus::options())->disabled() + Select::make('status')->options(ProjectStatus::options())->disabled() ->label(__('project.labels.status')) ->inlineLabel() ->columnSpanFull() ->required(), + TextInput::make('visible_status') + ->label(__('project.labels.visible_status')) + ->inlineLabel() + ->columnSpanFull() + ->formatStateUsing(function (Project $record) { + return __(sprintf('project.visible_status.%s', $record->visible_status)); + }) + ->hidden( + function (callable $get) { + return $get('status') != ProjectStatus::approved; + } + ) + ->disabled(), Forms\Components\Toggle::make('is_national') ->label(__('project.labels.is_national')) ->inlineLabel() ->columnSpanFull() ->reactive() ->required(), - Forms\Components\Select::make('counties') + Select::make('counties') ->relationship('counties', 'name') ->label(__('project.labels.counties')) ->inlineLabel() @@ -70,7 +86,7 @@ public static function form(Form $form): Form ->hidden(function (callable $get) { return $get('is_national') === true; }), - Forms\Components\Select::make('categories') + Select::make('categories') ->relationship('categories', 'name') ->label(__('project.labels.category')) ->inlineLabel() @@ -78,10 +94,10 @@ public static function form(Form $form): Form ->multiple() ->preload() ->required(), - Forms\Components\TextInput::make('name') + TextInput::make('name') ->required() ->maxLength(255), - Forms\Components\TextInput::make('target_budget') + TextInput::make('target_budget') ->required(), Forms\Components\DatePicker::make('start') ->required(), @@ -112,10 +128,10 @@ public static function form(Form $form): Form ->multiple() ->maxFiles(20), Forms\Components\Repeater::make('videos')->schema([ - Forms\Components\TextInput::make('url'), + TextInput::make('url'), ]), Forms\Components\Repeater::make('external_links')->schema([ - Forms\Components\TextInput::make('url'), + TextInput::make('url'), ]), ]); } @@ -130,10 +146,10 @@ public static function table(Table $table): Table 'heroicon-o-clock' => ProjectStatus::rejected->value, 'heroicon-o-check-circle' => ProjectStatus::approved->value, ]), - Tables\Columns\TextColumn::make('name'), - Tables\Columns\TextColumn::make('category'), + TextColumn::make('name'), + TextColumn::make('category'), - Tables\Columns\TextColumn::make('created_at')->date(), + TextColumn::make('created_at')->date(), ]); } @@ -186,16 +202,16 @@ public static function getPages(): array public static function getWidgetColumns(): array { return [ - Tables\Columns\TextColumn::make('id') + TextColumn::make('id') ->formatStateUsing(function (Project $record) { return sprintf('#%d', $record->id); }) ->label(__('project.labels.id')) ->sortable(), - Tables\Columns\TextColumn::make('name')->description(fn (Project $record) => $record->organization->name)->searchable(), - Tables\Columns\TextColumn::make('category')->formatStateUsing(fn (Project $record) => $record->categories->pluck('name')->join(', ')) + TextColumn::make('name')->description(fn (Project $record) => $record->organization->name)->searchable(), + TextColumn::make('category')->formatStateUsing(fn (Project $record) => $record->categories->pluck('name')->join(', ')) ->label(__('project.labels.category')), - Tables\Columns\TextColumn::make('counties')->formatStateUsing(function (Project $record) { + TextColumn::make('counties')->formatStateUsing(function (Project $record) { if ($record->is_national) { return __('project.labels.national'); } @@ -203,13 +219,13 @@ public static function getWidgetColumns(): array return $record->counties->pluck('name')->join(', '); }) ->label(__('project.labels.counties')), - Tables\Columns\TextColumn::make('target_budget')->formatStateUsing(function (Project $record) { + TextColumn::make('target_budget')->formatStateUsing(function (Project $record) { return number_format($record->target_budget, 2, ',', '.'); }) ->label(__('project.labels.target_budget')), - Tables\Columns\TextColumn::make('status_updated_at')->date('d-m-Y H:i:s') + TextColumn::make('status_updated_at')->date('d-m-Y H:i:s') ->label(__('project.labels.status_updated_at')), - Tables\Columns\TextColumn::make('created_at')->date('d-m-Y H:i:s') + TextColumn::make('created_at')->date('d-m-Y H:i:s') ->label(__('project.labels.created_at')), ]; } diff --git a/app/Filament/Resources/ProjectResource/Widgets/ApprovedProject.php b/app/Filament/Resources/ProjectResource/Widgets/ApprovedProject.php index 6563d507..8c9d2959 100644 --- a/app/Filament/Resources/ProjectResource/Widgets/ApprovedProject.php +++ b/app/Filament/Resources/ProjectResource/Widgets/ApprovedProject.php @@ -7,6 +7,8 @@ use App\Enums\ProjectStatus; use App\Models\Project; use Filament\Tables\Actions\Action; +use Filament\Tables\Columns\BadgeColumn; +use Filament\Tables\Columns\TextColumn; use Illuminate\Database\Eloquent\Builder; class ApprovedProject extends BaseProjectWidget @@ -15,12 +17,24 @@ class ApprovedProject extends BaseProjectWidget protected function getTableHeading(): string { - return __('project.heading.approved',['number' => $this->getTableQuery()->count()]); + return __('project.heading.approved', ['number' => $this->getTableQuery()->count()]); } protected function getTableQuery(): Builder { - return Project::query()->select(['id','organization_id','name','target_budget','is_national','created_at','status_updated_at','status'])->whereIsApproved(); + return Project::query()->select([ + 'id', + 'organization_id', + 'name', + 'target_budget', + 'is_national', + 'created_at', + 'status_updated_at', + 'archived_at', + 'start', + 'end', + 'status', + ])->whereIsApproved(); } protected function getTableQueryStringIdentifier(): ?string @@ -63,4 +77,46 @@ protected function getTableActions(): array ->icon(null), ]; } + + protected function getTableColumns(): array + { + return [ + TextColumn::make('id') + ->formatStateUsing(function (Project $record) { + return sprintf('#%d', $record->id); + }) + ->label(__('project.labels.id')) + ->sortable(), + BadgeColumn::make('visible_status') + ->label('status') + ->colors( + [ + 'primary' => 'published', + 'success' => 'open', + 'warning' => 'starting_soon', + 'info' => 'archived', + 'danger' => 'close', + ] + )->sortable(), + TextColumn::make('name')->description(fn (Project $record) => $record->organization->name)->searchable(), + TextColumn::make('category')->formatStateUsing(fn (Project $record) => $record->categories->pluck('name')->join(', ')) + ->label(__('project.labels.category')), + TextColumn::make('counties')->formatStateUsing(function (Project $record) { + if ($record->is_national) { + return __('project.labels.national'); + } + + return $record->counties->pluck('name')->join(', '); + }) + ->label(__('project.labels.counties')), + TextColumn::make('target_budget')->formatStateUsing(function (Project $record) { + return number_format($record->target_budget, 2, ',', '.'); + }) + ->label(__('project.labels.target_budget')), + TextColumn::make('status_updated_at')->date('d-m-Y H:i:s') + ->label(__('project.labels.status_updated_at')), + TextColumn::make('created_at')->date('d-m-Y H:i:s') + ->label(__('project.labels.created_at')), + ]; + } } diff --git a/app/Models/Organization.php b/app/Models/Organization.php index b93d76da..f2217e7c 100644 --- a/app/Models/Organization.php +++ b/app/Models/Organization.php @@ -188,6 +188,11 @@ public function scopeWhereDoesntHaveDonations(Builder $query): Builder return $query->whereDoesntHave('projects.donations'); } + public function EuPlatescIsActive(): bool + { + return $this->eu_platesc_merchant_id !== null && $this->eu_platesc_private_key !== null; + } + public function getActivitylogOptions(): LogOptions { return LogOptions::defaults() diff --git a/app/Models/Project.php b/app/Models/Project.php index 5e7e1c78..33aaee84 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -193,4 +193,24 @@ public function getIsEndingSoonAttribute(): bool return $this->end->diffInDays(today()) <= 5; } + + public function getVisibleStatusAttribute(): string + { + if ($this->isStartingSoon()) { + return 'starting_soon'; + } + if ($this->isOpen()) { + return 'open'; + } + if ($this->isClose()) + { + return 'close'; + } + if ($this->isArchived()) { + return 'archived'; + } + + return $this->status->value; + + } } diff --git a/app/Traits/HasProjectStatus.php b/app/Traits/HasProjectStatus.php index c73ccfcd..f3c53f63 100644 --- a/app/Traits/HasProjectStatus.php +++ b/app/Traits/HasProjectStatus.php @@ -29,6 +29,36 @@ public function isRejected(): bool return $this->status === ProjectStatus::rejected; } + public function isDraft(): bool + { + return $this->status === ProjectStatus::draft; + } + + public function isPublished(): bool + { + return $this->isApproved() && $this->archived_at === null; + } + + public function isOpen(): bool + { + return $this->isPublished() && $this->start->isPast() && $this->end->isFuture(); + } + + public function isArchived(): bool + { + return $this->isApproved() && ! empty($this->archived_at); + } + + public function isStartingSoon(): bool + { + return $this->isPublished() && ($this->start->isFuture() || ! $this->organization->EuPlatescIsActive()); + } + + public function isClose(): bool + { + return $this->isPublished() && $this->end->isPast(); + } + public function scopeWhereIsPending(Builder $query): Builder { return $query->where('status', ProjectStatus::pending); @@ -61,6 +91,12 @@ public function scopeWhereStartsSoon(Builder $query): Builder { return $query->whereIsPublished() ->whereDate('start', '>=', now()) + ->orWhere( + fn (Builder $query) => $query->whereHas( + 'organization', + fn (Builder $query) => $query->whereDoesntHaveEuPlatesc() + ) + ) ->orderBy('start'); } diff --git a/lang/ro/project.php b/lang/ro/project.php index 040ff587..fc81abb0 100644 --- a/lang/ro/project.php +++ b/lang/ro/project.php @@ -9,15 +9,15 @@ 'category' => 'Categorie', 'counties' => 'Județe', 'created_from' => 'Creată de la', - 'status_updated_at_from' => 'Trimis spre apr. de la', + 'status_updated_at_from' => 'Status schimbat de la', 'created_until' => 'Creată până la', - 'status_updated_at_until' => 'Trimis spre apr. pana la', + 'status_updated_at_until' => 'Status schimbat pana la', ], 'status_arr' => [ 'draft' => 'Draft', 'pending' => 'În așteptare', - 'active' => 'Activă', - 'disabled' => 'Inactivă', + 'approved' => 'Aprobat', + 'rejected' => 'Dezactivat', ], 'actions' => [ 'view' => 'Vezi', @@ -66,9 +66,18 @@ 'accepting_comments' => 'Acceptă comentarii', 'videos' => 'Video-uri', 'external_links' => 'Link-uri externe', - 'status_updated_at' => 'Trimis spre apr.', + 'status_updated_at' => 'Status schimbat la data', 'preview_image' => 'Imagine de prezentare', 'gallery' => 'Galerie', + 'visible_status' => 'Status in platforma public', + ], + 'visible_status'=>[ + 'published' => 'Publicat', + 'archived' => 'Arhivat', + 'open' => 'Deschis', + 'close' => 'Închis', + 'starting_soon' => 'Începe în curând', + ] ];