From 0db9d208731cc6d67ce9d8955c305fd76ba4f1d7 Mon Sep 17 00:00:00 2001 From: RichardGL11 Date: Mon, 17 Nov 2025 17:45:11 -0300 Subject: [PATCH 1/4] feat: talks time --- .../database/factories/EventFactory.php | 4 +- .../events/database/factories/TalkFactory.php | 2 + ...11_05_192008_create_events_talks_table.php | 2 + .../events/src/Enums/Talks/TalkStatusEnum.php | 6 +- .../Resources/Talks/Schemas/TalkForm.php | 84 ++++++++++++------- .../Filament/App/Talks/Schemas/TalkForm.php | 69 ++++++++------- .../Shared/Schemas/StartEndFieldsSchema.php | 66 +++++++++++++++ app-modules/events/src/Models/EventModel.php | 37 ++++++++ app-modules/events/src/Models/Talk.php | 4 + .../Filament/Admin/Talk/CreateTalk.php | 3 + .../Filament/App/Talks/CreateTalkTest.php | 49 +++++++++++ app/Rules/AvailableTalkSchedule.php | 39 +++++++++ 12 files changed, 304 insertions(+), 61 deletions(-) create mode 100644 app-modules/events/src/Filament/Shared/Schemas/StartEndFieldsSchema.php create mode 100644 app/Rules/AvailableTalkSchedule.php diff --git a/app-modules/events/database/factories/EventFactory.php b/app-modules/events/database/factories/EventFactory.php index 77b67c702..199ef3024 100644 --- a/app-modules/events/database/factories/EventFactory.php +++ b/app-modules/events/database/factories/EventFactory.php @@ -29,9 +29,9 @@ public function definition(): array 'active' => true, 'title' => fake()->sentence(4), 'description' => fake()->text(), - 'event_at' => Date::now(), + 'event_at' => Date::today(), 'start_at' => Date::now(), - 'end_at' => Date::now(), + 'end_at' => Date::today()->endOfDay(), 'location' => fake()->sentence(3), 'max_attendees' => fake()->numberBetween(10, 100), 'attendees_count' => 0, diff --git a/app-modules/events/database/factories/TalkFactory.php b/app-modules/events/database/factories/TalkFactory.php index e49da1359..b52c6526c 100644 --- a/app-modules/events/database/factories/TalkFactory.php +++ b/app-modules/events/database/factories/TalkFactory.php @@ -29,6 +29,8 @@ public function definition(): array 'field_type' => fake()->word(), 'title' => fake()->word(), 'description' => fake()->text(), + 'starts_at' => Date::now(), + 'ends_at' => Date::now(), 'created_at' => Date::now(), 'updated_at' => Date::now(), ]; diff --git a/app-modules/events/database/migrations/2025_11_05_192008_create_events_talks_table.php b/app-modules/events/database/migrations/2025_11_05_192008_create_events_talks_table.php index e4a54080e..b1898a5a3 100644 --- a/app-modules/events/database/migrations/2025_11_05_192008_create_events_talks_table.php +++ b/app-modules/events/database/migrations/2025_11_05_192008_create_events_talks_table.php @@ -24,6 +24,8 @@ public function up(): void $table->string('field_type'); // IA, Dev, Design, etc. $table->string('title'); $table->text('description'); + $table->timestamp('starts_at'); + $table->timestamp('ends_at'); $table->timestamps(); }); } diff --git a/app-modules/events/src/Enums/Talks/TalkStatusEnum.php b/app-modules/events/src/Enums/Talks/TalkStatusEnum.php index ed9c1c1f2..de1f7d4e0 100644 --- a/app-modules/events/src/Enums/Talks/TalkStatusEnum.php +++ b/app-modules/events/src/Enums/Talks/TalkStatusEnum.php @@ -13,6 +13,7 @@ enum TalkStatusEnum: string implements HasColor, HasIcon, HasLabel { case Pending = 'pending'; + case Rejected = 'rejected'; case Accepted = 'accepted'; case Done = 'done'; @@ -21,6 +22,7 @@ public function getColor(): array return match ($this) { self::Pending => Color::Yellow, self::Accepted => Color::Blue, + self::Rejected => Color::Red, self::Done => Color::Green, }; } @@ -30,6 +32,7 @@ public function getIcon(): Heroicon return match ($this) { self::Pending => Heroicon::Clock, self::Accepted => Heroicon::CircleStack, + self::Rejected => Heroicon::XCircle, self::Done => Heroicon::ArrowUpCircle, }; } @@ -38,7 +41,8 @@ public function getLabel(): string { return match ($this) { self::Pending => 'Pending', - self::Accepted => 'Live', + self::Accepted => 'Accepted', + self::Rejected => 'Rejected', self::Done => 'Done', }; } diff --git a/app-modules/events/src/Filament/Admin/Resources/Talks/Schemas/TalkForm.php b/app-modules/events/src/Filament/Admin/Resources/Talks/Schemas/TalkForm.php index 8bbac6c65..4391cafab 100644 --- a/app-modules/events/src/Filament/Admin/Resources/Talks/Schemas/TalkForm.php +++ b/app-modules/events/src/Filament/Admin/Resources/Talks/Schemas/TalkForm.php @@ -7,8 +7,10 @@ use Filament\Forms\Components\RichEditor; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; +use Filament\Schemas\Components\Flex; +use Filament\Schemas\Components\Section; use Filament\Schemas\Schema; -use He4rt\Events\Enums\Talks\TalkStatusEnum; +use He4rt\Events\Filament\Shared\Schemas\StartEndFieldsSchema; class TalkForm { @@ -16,34 +18,58 @@ public static function configure(Schema $schema): Schema { return $schema ->components([ - Select::make('tenant_id') - ->label('Tenant') - ->relationship('tenant', 'name') - ->required(), - Select::make('user_id') - ->label('User') - ->relationship('user', 'username') - ->required(), - Select::make('event_id') - ->label('EventModel') - ->relationship('event', 'title') - ->required(), - TextInput::make('title') - ->label('Title') - ->minLength(3) - ->maxLength(255) - ->required(), - Select::make('status') - ->enum(TalkStatusEnum::class) - ->options(TalkStatusEnum::class) - ->required(), - TextInput::make('field_type') - ->maxLength(255) - ->required(), - RichEditor::make('description') - ->minLength(5) - ->maxLength(255) - ->required(), + + Flex::make([ + Section::make('Proposta da Palestra') + ->description('Defina o evento, título e tipo da sua proposta.') + ->icon('heroicon-m-clipboard-document-list') + ->schema([ + Select::make('tenant_id') + ->label('Tenant') + ->relationship('tenant', 'name') + ->required() + ->live() + ->columnSpan(1), + Select::make('user_id') + ->label('User') + ->relationship('user', 'username') + ->required() + ->live() + ->columnSpan(1), + + TextInput::make('field_type') + ->label('Tipo') + ->minLength(3) + ->maxlength(255) + ->required() + ->columnSpan(1), + TextInput::make('title') + ->label('Título da Proposta') + ->minLength(3) + ->maxlength(255) + ->required() + ->columnSpanFull(), + Section::make('Horários da Palestra') + ->description('Forneça os horários da sua palestra') + ->schema( + StartEndFieldsSchema::make(), + ), + ])->columnSpan(3), + + ]) + ->columnSpanFull(), + + Section::make('Detalhes e Conteúdo') + ->description('Forneça a descrição completa da sua palestra e o que o público aprenderá.') + ->icon('heroicon-m-document-text') + ->schema([ + RichEditor::make('description') + ->label('Descrição Completa') + ->required() + ->columnSpanFull(), + ]) + ->columnSpanFull(), + ]); } } diff --git a/app-modules/events/src/Filament/App/Talks/Schemas/TalkForm.php b/app-modules/events/src/Filament/App/Talks/Schemas/TalkForm.php index 33cab1dd2..60762c200 100644 --- a/app-modules/events/src/Filament/App/Talks/Schemas/TalkForm.php +++ b/app-modules/events/src/Filament/App/Talks/Schemas/TalkForm.php @@ -9,9 +9,11 @@ use Filament\Forms\Components\RichEditor; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; +use Filament\Schemas\Components\Flex; use Filament\Schemas\Components\Section; use Filament\Schemas\Schema; use He4rt\Events\Enums\Talks\TalkStatusEnum; +use He4rt\Events\Filament\Shared\Schemas\StartEndFieldsSchema; use Illuminate\Database\Eloquent\Builder; class TalkForm @@ -20,36 +22,45 @@ public static function configure(Schema $schema): Schema { return $schema ->components([ - Section::make('Proposta da Palestra') - ->description('Defina o evento, título e tipo da sua proposta.') - ->icon('heroicon-m-clipboard-document-list') - ->columns(3) - ->columnSpanFull() - ->schema([ - Select::make('event_id') - ->label('Evento') - ->searchable() - ->relationship( - name: 'event', - titleAttribute: 'title', - modifyQueryUsing: fn (Builder $query) => $query->where('tenant_id', Filament::getTenant()->getKey()) - ) - ->required() - ->columnSpan(2), + Flex::make([ + Section::make('Proposta da Palestra') + ->description('Defina o evento, título e tipo da sua proposta.') + ->icon('heroicon-m-clipboard-document-list') + ->schema([ + Select::make('event_id') + ->label('Evento') + ->preload() + ->searchable() + ->relationship( + name: 'event', + titleAttribute: 'title', + modifyQueryUsing: fn (Builder $query) => $query->where('tenant_id', Filament::getTenant()->getKey()) + ) + ->required() + ->live() + ->columnSpan(1), - TextInput::make('field_type') - ->label('Tipo') - ->minLength(3) - ->maxlength(255) - ->required() - ->columnSpan(1), - TextInput::make('title') - ->label('Título da Proposta') - ->minLength(3) - ->maxlength(255) - ->required() - ->columnSpanFull(), - ]), + TextInput::make('field_type') + ->label('Tipo') + ->minLength(3) + ->maxlength(255) + ->required() + ->columnSpan(1), + TextInput::make('title') + ->label('Título da Proposta') + ->minLength(3) + ->maxlength(255) + ->required() + ->columnSpanFull(), + Section::make('Horários da Palestra') + ->description('Forneça os horários da sua palestra') + ->schema( + StartEndFieldsSchema::make(), + ), + ])->columnSpan(3), + + ]) + ->columnSpanFull(), Section::make('Detalhes e Conteúdo') ->description('Forneça a descrição completa da sua palestra e o que o público aprenderá.') diff --git a/app-modules/events/src/Filament/Shared/Schemas/StartEndFieldsSchema.php b/app-modules/events/src/Filament/Shared/Schemas/StartEndFieldsSchema.php new file mode 100644 index 000000000..6aab309f2 --- /dev/null +++ b/app-modules/events/src/Filament/Shared/Schemas/StartEndFieldsSchema.php @@ -0,0 +1,66 @@ +label('Starts at') + ->minDate(function (Get $get): ?Carbon { + + /** @var EventModel $event */ + $event = EventModel::query()->where('id', $get('event_id'))->first(); + if ($event) { + return Date::parse($event->start_at); + } + + return null; + }) + ->required(), + DateTimePicker::make('ends_at') + ->maxDate(function (Get $get): ?Carbon { + + /** @var EventModel $event */ + $event = EventModel::query()->where('id', $get('event_id'))->first(); + + if ($event) { + return Date::parse($event->end_at); + } + + return null; + }) + ->after('starts_at') + ->rules([ + function (Get $get): array { + $eventId = $get('event_id'); + $startsAt = $get('starts_at'); + + if ($eventId && $startsAt) { + return [ + new AvailableTalkSchedule( + eventId: (int) $eventId, + start_at: (string) $startsAt, + ), + ]; + } + + return []; + }, + ]) + ->label('Ends at') + ->required(), + ]; + } +} diff --git a/app-modules/events/src/Models/EventModel.php b/app-modules/events/src/Models/EventModel.php index 21a01cabd..7da868dc2 100644 --- a/app-modules/events/src/Models/EventModel.php +++ b/app-modules/events/src/Models/EventModel.php @@ -9,15 +9,19 @@ use He4rt\Events\Database\Factories\EventFactory; use He4rt\Events\Enums\AttendingStatusEnum; use He4rt\Events\Enums\EventTypeEnum; +use He4rt\Events\Enums\Talks\TalkStatusEnum; use He4rt\Events\Models\Pivot\EventAttend; use He4rt\Tenant\Models\Tenant; use He4rt\User\Models\User; use Illuminate\Database\Eloquent\Attributes\Scope; use Illuminate\Database\Eloquent\Attributes\UseFactory; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Database\Eloquent\Relations\Pivot; /** @@ -32,6 +36,7 @@ * @property int $waitlist_count * @property int $tenant_id * @property Date $end_at + * @property Date $start_at */ #[UseFactory(EventFactory::class)] class EventModel extends Model @@ -135,6 +140,38 @@ public function tenant(): BelongsTo return $this->belongsTo(Tenant::class); } + /** + * @return HasMany + */ + public function talks(): HasMany + { + return $this->hasMany(Talk::class, 'event_id'); + } + + /** + * @return HasManyThrough + */ + public function speakers(): HasManyThrough + { + return $this->hasManyThrough(User::class, Talk::class, 'user_id'); + } + + #[Scope] + protected function availableHours(Builder $query, string $start, string $end): Builder + { + $query->where('start_at', '<=', $start) + ->where('end_at', '>=', $end); + + return $query->whereDoesntHave('talks', function (Builder $talkQuery) use ($start, $end): void { + $talkQuery + ->where('status', '=', TalkStatusEnum::Accepted->value) + ->orWhere('status', '=', TalkStatusEnum::Done->value); + + $talkQuery->where('starts_at', '<', $end) + ->where('ends_at', '>', $start); + }); + } + #[Scope] protected function active($query) { diff --git a/app-modules/events/src/Models/Talk.php b/app-modules/events/src/Models/Talk.php index d90cde020..c0a535831 100644 --- a/app-modules/events/src/Models/Talk.php +++ b/app-modules/events/src/Models/Talk.php @@ -28,6 +28,8 @@ class Talk extends Model 'field_type', 'title', 'description', + 'starts_at', + 'ends_at', ]; /** @@ -58,6 +60,8 @@ protected function casts(): array { return [ 'status' => TalkStatusEnum::class, + 'starts_at' => 'datetime', + 'ends_at' => 'datetime', ]; } } diff --git a/app-modules/events/tests/Feature/Filament/Admin/Talk/CreateTalk.php b/app-modules/events/tests/Feature/Filament/Admin/Talk/CreateTalk.php index 6790311d7..5756b5c6e 100644 --- a/app-modules/events/tests/Feature/Filament/Admin/Talk/CreateTalk.php +++ b/app-modules/events/tests/Feature/Filament/Admin/Talk/CreateTalk.php @@ -5,6 +5,7 @@ use App\Enums\FilamentPanel; use Filament\Facades\Filament; use He4rt\Events\Enums\Talks\TalkStatusEnum; +use He4rt\Events\Filament\Admin\Resources\Talks\Pages\CreateTalk; use He4rt\Events\Models\EventModel; use He4rt\Events\Models\Talk; use He4rt\User\Models\User; @@ -35,6 +36,8 @@ 'status' => TalkStatusEnum::Pending->value, 'field_type' => 'some text right there', 'description' => 'description you know', + 'starts_at' => now(), + 'ends_at' => now()->addHour(), ]) ->call('create') ->assertHasNoFormErrors(); diff --git a/app-modules/events/tests/Feature/Filament/App/Talks/CreateTalkTest.php b/app-modules/events/tests/Feature/Filament/App/Talks/CreateTalkTest.php index 790b8eb2b..67d35f760 100644 --- a/app-modules/events/tests/Feature/Filament/App/Talks/CreateTalkTest.php +++ b/app-modules/events/tests/Feature/Filament/App/Talks/CreateTalkTest.php @@ -4,6 +4,7 @@ use App\Enums\FilamentPanel; use Filament\Facades\Filament; +use He4rt\Events\Enums\Talks\TalkStatusEnum; use He4rt\Events\Filament\App\Talks\Pages\CreateTalk; use He4rt\Events\Models\EventModel; use He4rt\Events\Models\Talk; @@ -36,6 +37,8 @@ 'field_type' => 'whatever', 'title' => 'title whatever', 'description' => 'description whatever', + 'starts_at' => now()->addMinutes(10), + 'ends_at' => now()->addHour(), ]) ->call('create') ->assertHasNoFormErrors(); @@ -67,6 +70,52 @@ ]); }); +describe('TalkTimeIsAvailable Rule', function (): void { + + it('should should not be able to create a talk if there is already one at this time', function (): void { + $start = now()->addHour(); + $end = now()->addhours(3); + Talk::factory()->recycle($this->event)->create([ + 'starts_at' => $start, + 'ends_at' => $end, + 'status' => TalkStatusEnum::Accepted, + ]); + livewire(CreateTalk::class) + ->assertOk() + ->fillForm([ + 'event_id' => $this->event->getKey(), + 'field_type' => 'whatever', + 'title' => 'title whatever', + 'description' => 'description whatever', + 'starts_at' => $start, + 'ends_at' => $end, + ]) + ->call('create') + ->assertHasFormErrors(['ends_at']); + }); + it('should should be able to create a talk if there is already one but is not accepted yet', function (): void { + $start = now()->addHour(); + $end = now()->addhours(3); + Talk::factory()->recycle($this->event)->create([ + 'starts_at' => $start, + 'ends_at' => $end, + 'status' => TalkStatusEnum::Pending, + ]); + livewire(CreateTalk::class) + ->assertOk() + ->fillForm([ + 'event_id' => $this->event->getKey(), + 'field_type' => 'whatever', + 'title' => 'title whatever', + 'description' => 'description whatever', + 'starts_at' => $start, + 'ends_at' => $end, + ]) + ->call('create') + ->assertHasNoFormErrors(); + }); +}); + describe('validation rules', function (): void { test('field_type::validations', function ($rule, $value): void { livewire(CreateTalk::class) diff --git a/app/Rules/AvailableTalkSchedule.php b/app/Rules/AvailableTalkSchedule.php new file mode 100644 index 000000000..0eefec2be --- /dev/null +++ b/app/Rules/AvailableTalkSchedule.php @@ -0,0 +1,39 @@ +start_at)->toDateTimeString(); + $end = Date::parse($value)->toDateTimeString(); + + $isAvailable = EventModel::query() + ->where('id', $this->eventId) + ->availableHours(start: $start, end: $end) + ->exists(); + + if (! $isAvailable) { + $fail(sprintf('O Horário %s até %s não está disponível.', $end, $start)); + } + } +} From 4cdbb446c2b48a2c2a12cdbd28426d65802bbfd4 Mon Sep 17 00:00:00 2001 From: RichardGL11 Date: Mon, 17 Nov 2025 18:35:38 -0300 Subject: [PATCH 2/4] wip: seeder --- app/Rules/AvailableTalkSchedule.php | 6 +-- database/seeders/BaseSeeder.php | 64 ++++++++++++++++++++++++++++ database/seeders/DatabaseSeeder.php | 51 ++-------------------- database/seeders/ThreeDotsSeeder.php | 53 +++++++++++++++++++++++ 4 files changed, 124 insertions(+), 50 deletions(-) create mode 100644 database/seeders/BaseSeeder.php create mode 100644 database/seeders/ThreeDotsSeeder.php diff --git a/app/Rules/AvailableTalkSchedule.php b/app/Rules/AvailableTalkSchedule.php index 0eefec2be..f59d16f5f 100644 --- a/app/Rules/AvailableTalkSchedule.php +++ b/app/Rules/AvailableTalkSchedule.php @@ -4,11 +4,11 @@ namespace App\Rules; -use Illuminate\Support\Facades\Date; -use Illuminate\Translation\PotentiallyTranslatedString; use Closure; use He4rt\Events\Models\EventModel; use Illuminate\Contracts\Validation\ValidationRule; +use Illuminate\Support\Facades\Date; +use Illuminate\Translation\PotentiallyTranslatedString; class AvailableTalkSchedule implements ValidationRule { @@ -20,7 +20,7 @@ public function __construct( /** * Run the validation rule. * - * @param Closure(string, ?string=):PotentiallyTranslatedString $fail + * @param Closure(string, ?string=):PotentiallyTranslatedString $fail */ public function validate(string $attribute, mixed $value, Closure $fail): void { diff --git a/database/seeders/BaseSeeder.php b/database/seeders/BaseSeeder.php new file mode 100644 index 000000000..9addc6445 --- /dev/null +++ b/database/seeders/BaseSeeder.php @@ -0,0 +1,64 @@ +create([ + 'username' => 'admin', + 'name' => 'admin', + 'email' => 'admin@admin.com', + 'password' => Hash::make('admin'), + ]); + + Information::factory()->recycle($user)->create(); + Address::factory()->recycle($user)->create(); + + $tenant = Tenant::factory() + ->for($user, 'owner') + ->afterCreating(fn (Tenant $tenant) => $tenant->members()->attach($user)) + ->create([ + 'name' => 'He4rt Developers', + 'slug' => 'he4rt', + ]); + + Character::factory() + ->recycle($user) + ->recycle($tenant) + ->createOne(); + + EventModel::factory()->count(10) + ->withStatus() + ->recycle($tenant) + ->create([ + 'end_at' => Date::tomorrow(), + ]); + + Season::factory() + ->recycle($tenant) + ->create([ + 'name' => 'Season 1', + 'started_at' => now()->subMonth(), + 'ended_at' => today(), + ]); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 71d9bf3e0..a686c3f11 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -5,16 +5,7 @@ namespace Database\Seeders; // use Illuminate\Database\Console\Seeds\WithoutModelEvents; -use He4rt\Character\Models\Character; -use He4rt\Events\Models\EventModel; -use He4rt\Season\Models\Season; -use He4rt\Tenant\Models\Tenant; -use He4rt\User\Models\Address; -use He4rt\User\Models\Information; -use He4rt\User\Models\User; use Illuminate\Database\Seeder; -use Illuminate\Support\Facades\Date; -use Illuminate\Support\Facades\Hash; final class DatabaseSeeder extends Seeder { @@ -23,43 +14,9 @@ final class DatabaseSeeder extends Seeder */ public function run(): void { - $user = User::factory() - ->create([ - 'username' => 'admin', - 'name' => 'admin', - 'email' => 'admin@admin.com', - 'password' => Hash::make('admin'), - ]); - - Information::factory()->recycle($user)->create(); - Address::factory()->recycle($user)->create(); - - $tenant = Tenant::factory() - ->for($user, 'owner') - ->afterCreating(fn (Tenant $tenant) => $tenant->members()->attach($user)) - ->create([ - 'name' => 'He4rt Developers', - 'slug' => 'he4rt', - ]); - - Character::factory() - ->recycle($user) - ->recycle($tenant) - ->createOne(); - - EventModel::factory()->count(10) - ->withStatus() - ->recycle($tenant) - ->create([ - 'end_at' => Date::tomorrow(), - ]); - - Season::factory() - ->recycle($tenant) - ->create([ - 'name' => 'Season 1', - 'started_at' => now()->subMonth(), - 'ended_at' => today(), - ]); + $this->call([ + BaseSeeder::class, + ThreeDotsSeeder::class, + ]); } } diff --git a/database/seeders/ThreeDotsSeeder.php b/database/seeders/ThreeDotsSeeder.php new file mode 100644 index 000000000..f96c89bed --- /dev/null +++ b/database/seeders/ThreeDotsSeeder.php @@ -0,0 +1,53 @@ +where('name', '=', 'admin')->first(); + + $tenant = Tenant::factory() + ->for($user, 'owner') + ->afterCreating(fn (Tenant $tenant) => $tenant->members()->attach($user)) + ->create([ + 'name' => '3 Pontos', + 'slug' => '3-pontos', + ]); + + $event = EventModel::factory() + ->withStatus() + ->create([ + 'title' => 'Evento Da Três Pontos', + 'event_type' => EventTypeEnum::Workshop, + 'slug' => '3-pontos-evento', + 'description' => 'Participe do primeiro evento presencial da 3pontos', + 'event_at' => Date::createFromFormat('m-d-Y h:i:s A', '11-29-2025 02:00:00 PM'), + 'start_at' => Date::createFromFormat('m-d-Y h:i:s A', '11-29-2025 02:00:00 PM'), + 'end_at' => Date::createFromFormat('m-d-Y h:i:s A', '11-29-2025 07:00:00 PM'), + 'location' => 'Avenida Paulista, 1666, São Paulo - SP', + 'max_attendees' => 50, + 'attendees_count' => 30, + 'tenant_id' => $tenant->getKey(), + ]); + + Talk::factory() + ->recycle($tenant) + ->recycle($event) + ->count(4); + } +} From 7efe8b3a5be1664acca3a57f2c71e825cb754189 Mon Sep 17 00:00:00 2001 From: RichardGL11 Date: Tue, 18 Nov 2025 13:39:47 -0300 Subject: [PATCH 3/4] style: pint --- database/seeders/ThreeDotsSeeder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/seeders/ThreeDotsSeeder.php b/database/seeders/ThreeDotsSeeder.php index f96c89bed..1bd9bdd46 100644 --- a/database/seeders/ThreeDotsSeeder.php +++ b/database/seeders/ThreeDotsSeeder.php @@ -4,13 +4,13 @@ namespace Database\Seeders; -use Illuminate\Support\Facades\Date; use He4rt\Events\Enums\EventTypeEnum; use He4rt\Events\Models\EventModel; use He4rt\Events\Models\Talk; use He4rt\Tenant\Models\Tenant; use He4rt\User\Models\User; use Illuminate\Database\Seeder; +use Illuminate\Support\Facades\Date; class ThreeDotsSeeder extends Seeder { From 13ebb71537282fede854e9f7c637352dbe710027 Mon Sep 17 00:00:00 2001 From: RichardGL11 Date: Tue, 18 Nov 2025 14:47:02 -0300 Subject: [PATCH 4/4] wip --- app-modules/events/src/Models/EventModel.php | 3 +-- database/seeders/ThreeDotsSeeder.php | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app-modules/events/src/Models/EventModel.php b/app-modules/events/src/Models/EventModel.php index 7da868dc2..bb880cb28 100644 --- a/app-modules/events/src/Models/EventModel.php +++ b/app-modules/events/src/Models/EventModel.php @@ -164,8 +164,7 @@ protected function availableHours(Builder $query, string $start, string $end): B return $query->whereDoesntHave('talks', function (Builder $talkQuery) use ($start, $end): void { $talkQuery - ->where('status', '=', TalkStatusEnum::Accepted->value) - ->orWhere('status', '=', TalkStatusEnum::Done->value); + ->whereIn('status', [TalkStatusEnum::Accepted->value, TalkStatusEnum::Done->value]); $talkQuery->where('starts_at', '<', $end) ->where('ends_at', '>', $start); diff --git a/database/seeders/ThreeDotsSeeder.php b/database/seeders/ThreeDotsSeeder.php index 1bd9bdd46..d75a9e3bc 100644 --- a/database/seeders/ThreeDotsSeeder.php +++ b/database/seeders/ThreeDotsSeeder.php @@ -31,7 +31,7 @@ public function run(): void $event = EventModel::factory() ->withStatus() - ->create([ + ->state([ 'title' => 'Evento Da Três Pontos', 'event_type' => EventTypeEnum::Workshop, 'slug' => '3-pontos-evento', @@ -43,11 +43,13 @@ public function run(): void 'max_attendees' => 50, 'attendees_count' => 30, 'tenant_id' => $tenant->getKey(), - ]); + ]) + ->create(); Talk::factory() ->recycle($tenant) ->recycle($event) - ->count(4); + ->count(4) + ->create(); } }