From 0b1a3ae96f026a9eb97224e32d10570b2c2ca2b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna-Sara=20S=C3=A9lea?= Date: Thu, 21 May 2026 18:40:00 +0200 Subject: [PATCH] New features with Mail and SMS --- Dockerfile | 9 +- .../Resources/EmailLogs/EmailLogResource.php | 77 ++++++++++++ .../EmailLogs/Pages/ListEmailLogs.php | 16 +++ .../Mailtemplates/MailtemplateResource.php | 8 +- .../Schemas/MailtemplateForm.php | 9 +- .../Tables/MailtemplatesTable.php | 3 + .../Participants/Schemas/ParticipantForm.php | 25 ++++ .../Participants/Tables/ParticipantsTable.php | 112 +++++++++++++----- .../Smstemplates/Pages/CreateSmstemplates.php | 11 ++ .../Smstemplates/Pages/EditSmstemplates.php | 19 +++ .../Smstemplates/Pages/ListSmstemplates.php | 19 +++ .../Smstemplates/Schemas/SmstemplatesForm.php | 29 +++++ .../Smstemplates/SmstemplatesResource.php | 54 +++++++++ .../Smstemplates/Tables/SmstemplatesTable.php | 46 +++++++ .../Volunteers/Tables/VolunteersTable.php | 52 +++----- .../Controllers/SmstemplateController.php | 44 +++++++ app/Mail/SmsMail.php | 12 +- app/Models/EmailLog.php | 32 +++++ app/Models/Mailtemplate.php | 8 +- app/Models/Participant.php | 5 + app/Models/Smstemplate.php | 15 +++ app/Providers/Filament/AdminPanelProvider.php | 12 ++ ...05_18_000000_create_smstemplates_table.php | 25 ++++ ...ke_type_nullable_in_smstemplates_table.php | 22 ++++ ..._smstemplate_id_to_mailtemplates_table.php | 22 ++++ ...6_05_18_000003_create_email_logs_table.php | 26 ++++ ...8_000004_add_error_to_email_logs_table.php | 22 ++++ resources/views/mail/sms.blade.php | 7 +- 28 files changed, 656 insertions(+), 85 deletions(-) create mode 100644 app/Filament/Resources/EmailLogs/EmailLogResource.php create mode 100644 app/Filament/Resources/EmailLogs/Pages/ListEmailLogs.php create mode 100644 app/Filament/Resources/Smstemplates/Pages/CreateSmstemplates.php create mode 100644 app/Filament/Resources/Smstemplates/Pages/EditSmstemplates.php create mode 100644 app/Filament/Resources/Smstemplates/Pages/ListSmstemplates.php create mode 100644 app/Filament/Resources/Smstemplates/Schemas/SmstemplatesForm.php create mode 100644 app/Filament/Resources/Smstemplates/SmstemplatesResource.php create mode 100644 app/Filament/Resources/Smstemplates/Tables/SmstemplatesTable.php create mode 100644 app/Http/Controllers/SmstemplateController.php create mode 100644 app/Models/EmailLog.php create mode 100644 app/Models/Smstemplate.php create mode 100644 database/migrations/2026_05_18_000000_create_smstemplates_table.php create mode 100644 database/migrations/2026_05_18_000001_make_type_nullable_in_smstemplates_table.php create mode 100644 database/migrations/2026_05_18_000002_add_smstemplate_id_to_mailtemplates_table.php create mode 100644 database/migrations/2026_05_18_000003_create_email_logs_table.php create mode 100644 database/migrations/2026_05_18_000004_add_error_to_email_logs_table.php diff --git a/Dockerfile b/Dockerfile index ab33816..a946350 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,11 @@ -FROM php:8.2-apache-buster +FROM php:8.2-apache-bookworm RUN usermod -u 1000 www-data RUN a2enmod rewrite RUN apt-get update \ - && apt-get install -y gnupg2 zlib1g-dev libzip-dev zlib1g-dev libpng-dev libfreetype6-dev libjpeg62-turbo-dev libmcrypt-dev libxml2-dev + && apt-get install -y gnupg2 zlib1g-dev libzip-dev libpng-dev libfreetype6-dev libjpeg62-turbo-dev libxml2-dev \ + && rm -rf /var/lib/apt/lists/* RUN docker-php-ext-install zip mysqli pdo pdo_mysql && docker-php-ext-enable mysqli pdo pdo_mysql sodium -RUN docker-php-ext-configure gd +RUN docker-php-ext-configure gd --with-freetype --with-jpeg RUN docker-php-ext-install gd RUN docker-php-ext-configure intl RUN docker-php-ext-install intl @@ -14,4 +15,4 @@ RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local ENV APACHE_DOCUMENT_ROOT /var/www/html/public RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf -RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf \ No newline at end of file +RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf diff --git a/app/Filament/Resources/EmailLogs/EmailLogResource.php b/app/Filament/Resources/EmailLogs/EmailLogResource.php new file mode 100644 index 0000000..09a4f0e --- /dev/null +++ b/app/Filament/Resources/EmailLogs/EmailLogResource.php @@ -0,0 +1,77 @@ +columns([ + TextColumn::make('created_at') + ->label('Sent at') + ->dateTime() + ->sortable(), + TextColumn::make('lan_id') + ->label('LAN ID') + ->sortable() + ->searchable(), + TextColumn::make('guardian_email') + ->label('Email') + ->searchable(), + TextColumn::make('mailtemplate.title') + ->label('Mail template') + ->searchable(), + TextColumn::make('smstemplate.title') + ->label('SMS template') + ->default('—'), + TextColumn::make('participant.first_name') + ->label('First name') + ->searchable(), + TextColumn::make('participant.surname') + ->label('Surname') + ->searchable(), + TextColumn::make('error') + ->label('Error') + ->wrap() + ->color('danger') + ->default('—') + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->defaultSort('created_at', 'desc') + ->filters([]) + ->recordActions([]) + ->toolbarActions([]); + } + + public static function getPages(): array + { + return [ + 'index' => ListEmailLogs::route('/'), + ]; + } + + public static function canCreate(): bool + { + return false; + } +} diff --git a/app/Filament/Resources/EmailLogs/Pages/ListEmailLogs.php b/app/Filament/Resources/EmailLogs/Pages/ListEmailLogs.php new file mode 100644 index 0000000..1e9aa09 --- /dev/null +++ b/app/Filament/Resources/EmailLogs/Pages/ListEmailLogs.php @@ -0,0 +1,16 @@ +required() ->columnSpanFull(), + Select::make('smstemplate_id') + ->label('SMS template') + ->options(Smstemplate::where('draft', false)->pluck('title', 'id')) + ->nullable() + ->columnSpanFull(), Toggle::make('draft') ->default(false) ->onColor('warning') diff --git a/app/Filament/Resources/Mailtemplates/Tables/MailtemplatesTable.php b/app/Filament/Resources/Mailtemplates/Tables/MailtemplatesTable.php index d027134..198cf18 100644 --- a/app/Filament/Resources/Mailtemplates/Tables/MailtemplatesTable.php +++ b/app/Filament/Resources/Mailtemplates/Tables/MailtemplatesTable.php @@ -7,6 +7,7 @@ use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; +use Filament\Tables\Columns\ToggleColumn; class MailtemplatesTable { @@ -16,6 +17,8 @@ class MailtemplatesTable ->columns([ TextColumn::make('title') ->searchable(), + ToggleColumn::make('draft') + ->sortable(), TextColumn::make('created_at') ->dateTime() ->sortable() diff --git a/app/Filament/Resources/Participants/Schemas/ParticipantForm.php b/app/Filament/Resources/Participants/Schemas/ParticipantForm.php index 292077e..c222f4c 100644 --- a/app/Filament/Resources/Participants/Schemas/ParticipantForm.php +++ b/app/Filament/Resources/Participants/Schemas/ParticipantForm.php @@ -2,6 +2,7 @@ namespace App\Filament\Resources\Participants\Schemas; +use Filament\Forms\Components\Placeholder; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; use Filament\Schemas\Schema; @@ -10,6 +11,7 @@ use Filament\Forms\Components\Select; use Filament\Forms\Components\Textarea; use Filament\Schemas\Components\Grid; use DiscoveryDesign\FilamentGaze\Forms\Components\GazeBanner; +use Illuminate\Support\HtmlString; class ParticipantForm { @@ -101,6 +103,29 @@ class ParticipantForm ->columnSpan('full'), Textarea::make('comment') ->columnSpan('full'), + Placeholder::make('email_log') + ->label('Emails sent') + ->columnSpan('full') + ->hidden(fn ($record) => $record === null) + ->content(function ($record) { + if (!$record) { + return '—'; + } + $logs = $record->emailLogs()->with(['mailtemplate', 'smstemplate'])->latest()->get(); + if ($logs->isEmpty()) { + return new HtmlString('No emails sent'); + } + $rows = $logs->map(function ($log) { + $date = $log->created_at->format('Y-m-d H:i'); + $mail = e($log->mailtemplate?->title ?? '—'); + $sms = $log->smstemplate ? ' + SMS: ' . e($log->smstemplate->title) : ''; + $error = $log->error + ? ' ⚠ ' . e($log->error) . '' + : ''; + return "
  • {$date} — {$mail}{$sms}{$error}
  • "; + })->join(''); + return new HtmlString(""); + }), ]); } } diff --git a/app/Filament/Resources/Participants/Tables/ParticipantsTable.php b/app/Filament/Resources/Participants/Tables/ParticipantsTable.php index be4be9b..1cbd9c2 100644 --- a/app/Filament/Resources/Participants/Tables/ParticipantsTable.php +++ b/app/Filament/Resources/Participants/Tables/ParticipantsTable.php @@ -2,12 +2,15 @@ namespace App\Filament\Resources\Participants\Tables; +use Filament\Actions\BulkAction; use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; +use Illuminate\Database\Eloquent\Collection; use Filament\Actions\EditAction; use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; +use App\Models\EmailLog; use App\Models\Participant; use App\Models\Mailtemplate; use Filament\Tables\Columns\SelectColumn; @@ -32,10 +35,12 @@ class ParticipantsTable { return $table ->paginated([10, 25, 50, 100, 'all']) + ->defaultPaginationPageOption(100) ->groups([ - Group::make('status') - ->label('Status') - ->collapsible(), + Group::make('status') + ->label('Status') + ->getTitleFromRecordUsing(fn ($record) => ucfirst($record->status)) + ->collapsible(), ]) ->defaultGroup('status') //->groupsOnly() @@ -59,7 +64,6 @@ class ParticipantsTable TextColumn::make('status') ->label('Status') ->badge() - ->summarize(Count::make()->label('')) ->color(fn (string $state): string => match ($state) { 'lan' => 'success', 'reserv' => 'warning', @@ -73,7 +77,8 @@ class ParticipantsTable ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('first_name') ->searchable() - ->sortable(), + ->sortable() + ->summarize(Count::make()->label('')), TextColumn::make('surname') ->searchable() ->sortable(), @@ -114,7 +119,16 @@ class ParticipantsTable ->sortable(), IconColumn::make('emailed') ->boolean() - ->sortable(), + ->sortable() + ->tooltip(function ($record) { + $logs = $record->emailLogs()->with(['mailtemplate', 'smstemplate'])->latest()->get(); + if ($logs->isEmpty()) { + return 'No emails sent'; + } + return $logs->map(fn($log) => + ' Mail: ' . ($log->mailtemplate?->title ?? '—') + )->join("\n"); + }), TextColumn::make('comment') ->sortable() ->toggleable(isToggledHiddenByDefault: true), @@ -161,34 +175,72 @@ class ParticipantsTable ->options(Mailtemplate::where('draft', false)->pluck('title', 'id')) ]) ->action(function (array $data, Participant $record) { - $mailContent = Mailtemplate::where('id', $data['mailtemplate'])->get(); - Mail::to($record->guardian_email) - ->send(new LanMail($mailContent, $record)); - Participant::where('id', $record->id)->update(['emailed' => true]); - Mail::to(config('app.smsUrl')) - ->send(new SmsMail($record)); - - }) - ->hidden(fn($record) => $record->emailed), - Action::make('sendRemindEmail') - ->label('Send remind email') - ->icon(Heroicon::Envelope) - ->schema([ - Select::make('mailtemplate') - ->label('Mailtemplate') - ->options(Mailtemplate::where('draft', false)->pluck('title', 'id')) - ]) - ->action(function (array $data, Participant $record) { - $mailContent = Mailtemplate::where('id', $data['mailtemplate'])->get(); - Mail::to($record->guardian_email) - ->queue(new LanMail($mailContent, $record)); - Participant::where('id', $record->id)->update(['emailed' => true]); - }) - ->hidden(fn($record) => !$record->emailed), + $mailtemplate = Mailtemplate::with('smstemplate')->find($data['mailtemplate']); + if ($record->guardian_email) { + $error = null; + try { + Mail::to($record->guardian_email) + ->send(new LanMail(collect([$mailtemplate]), $record)); + Participant::where('id', $record->id)->update(['emailed' => true]); + if ($mailtemplate->smstemplate && config('app.smsUrl')) { + Mail::to(config('app.smsUrl')) + ->send(new SmsMail($record, $mailtemplate->smstemplate->content)); + } + } catch (\Throwable $e) { + $error = $e->getMessage(); + } + EmailLog::create([ + 'participant_id' => $record->id, + 'lan_id' => $record->lan_id, + 'guardian_email' => $record->guardian_email, + 'mailtemplate_id' => $mailtemplate->id, + 'smstemplate_id' => $mailtemplate->smstemplate?->id, + 'error' => $error, + ]); + } + }), ]) ->toolbarActions([ BulkActionGroup::make([ DeleteBulkAction::make(), + BulkAction::make('bulkSendEmail') + ->label('Send email') + ->icon(Heroicon::Envelope) + ->schema([ + Select::make('mailtemplate') + ->label('Mailtemplate') + ->options(Mailtemplate::where('draft', false)->pluck('title', 'id')) + ->required(), + ]) + ->action(function (Collection $records, array $data) { + $mailtemplate = Mailtemplate::with('smstemplate')->find($data['mailtemplate']); + foreach ($records as $record) { + if (!$record->guardian_email) { + continue; + } + $error = null; + try { + Mail::to($record->guardian_email) + ->queue(new LanMail(collect([$mailtemplate]), $record)); + if ($mailtemplate->smstemplate && config('app.smsUrl')) { + Mail::to(config('app.smsUrl')) + ->queue(new SmsMail($record, $mailtemplate->smstemplate->content)); + } + } catch (\Throwable $e) { + $error = $e->getMessage(); + } + EmailLog::create([ + 'participant_id' => $record->id, + 'lan_id' => $record->lan_id, + 'guardian_email' => $record->guardian_email, + 'mailtemplate_id' => $mailtemplate->id, + 'smstemplate_id' => $mailtemplate->smstemplate?->id, + 'error' => $error, + ]); + } + $records->toQuery()->whereDoesntHave('emailLogs', fn ($q) => $q->whereNotNull('error'))->update(['emailed' => true]); + }) + ->deselectRecordsAfterCompletion(), ]), ]); } diff --git a/app/Filament/Resources/Smstemplates/Pages/CreateSmstemplates.php b/app/Filament/Resources/Smstemplates/Pages/CreateSmstemplates.php new file mode 100644 index 0000000..2da25ba --- /dev/null +++ b/app/Filament/Resources/Smstemplates/Pages/CreateSmstemplates.php @@ -0,0 +1,11 @@ +components([ + GazeBanner::make() + ->pollTimer(10) + ->hideOnCreate(), + TextInput::make('title') + ->required() + ->columnSpanFull(), + Toggle::make('draft') + ->default(false) + ->onColor('warning') + ->columnSpanFull(), + ]); + } +} diff --git a/app/Filament/Resources/Smstemplates/SmstemplatesResource.php b/app/Filament/Resources/Smstemplates/SmstemplatesResource.php new file mode 100644 index 0000000..dd7f0b3 --- /dev/null +++ b/app/Filament/Resources/Smstemplates/SmstemplatesResource.php @@ -0,0 +1,54 @@ + ListSmstemplates::route('/'), + 'create' => CreateSmstemplates::route('/create'), + 'edit' => EditSmstemplates::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/Smstemplates/Tables/SmstemplatesTable.php b/app/Filament/Resources/Smstemplates/Tables/SmstemplatesTable.php new file mode 100644 index 0000000..05a9823 --- /dev/null +++ b/app/Filament/Resources/Smstemplates/Tables/SmstemplatesTable.php @@ -0,0 +1,46 @@ +columns([ + TextColumn::make('title') + ->searchable() + ->sortable(), + ToggleColumn::make('draft') + ->sortable(), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + TernaryFilter::make('draft') + ->label('Draft'), + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Volunteers/Tables/VolunteersTable.php b/app/Filament/Resources/Volunteers/Tables/VolunteersTable.php index d9d47ff..cb25886 100644 --- a/app/Filament/Resources/Volunteers/Tables/VolunteersTable.php +++ b/app/Filament/Resources/Volunteers/Tables/VolunteersTable.php @@ -33,10 +33,8 @@ class VolunteersTable TextInputColumn::make('lan_id') ->label('ID') ->searchable() - ->sortable(), - IconColumn::make('emailed') - ->boolean() - ->sortable(), + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('first_name') ->searchable() ->sortable(), @@ -76,36 +74,22 @@ class VolunteersTable EditAction::make() ->modalWidth() ->slideOver(), - Action::make('sendEmail') - ->label('Send email') - ->icon(Heroicon::Envelope) - ->schema([ - Select::make('mailtemplate') - ->label('Mailtemplate') - ->options(Mailtemplate::all()->pluck('title', 'id')) - ]) - ->action(function (array $data, Volunteer $record) { - $mailContent = Mailtemplate::where('id', $data['mailtemplate'])->get(); - Mail::to($record->email) - ->queue(new LanMail($mailContent, $record)); - Volunteer::where('id', $record->id)->update(['emailed' => true]); - }) - ->hidden(fn($record) => $record->emailed), - Action::make('sendRemindEmail') - ->label('Send remind email') - ->icon(Heroicon::Envelope) - ->schema([ - Select::make('mailtemplate') - ->label('Mailtemplate') - ->options(Mailtemplate::all()->pluck('title', 'id')) - ]) - ->action(function (array $data, Volunteer $record) { - $mailContent = Mailtemplate::where('id', $data['mailtemplate'])->get(); - Mail::to($record->email) - ->send(new LanMail($mailContent, $record)); - Volunteer::where('id', $record->id)->update(['emailed' => true]); - }) - ->hidden(fn($record) => !$record->emailed) + //Action::make('sendEmail') + //->label('Send email') + //->icon(Heroicon::Envelope) + //->schema([ + // Select::make('mailtemplate') + // ->label('Mailtemplate') + // ->options(Mailtemplate::all()->pluck('title', 'id')) + //]) + //->action(function (array $data, Volunteer $record) { + // if ($record->email) { + // $mailContent = Mailtemplate::where('id', $data['mailtemplate'])->get(); + // Mail::to($record->email) + // ->queue(new LanMail($mailContent, $record)); + // Volunteer::where('id', $record->id)->update(['emailed' => true]); + // } + //}), ]) ->toolbarActions([ BulkActionGroup::make([ diff --git a/app/Http/Controllers/SmstemplateController.php b/app/Http/Controllers/SmstemplateController.php new file mode 100644 index 0000000..2dfa783 --- /dev/null +++ b/app/Http/Controllers/SmstemplateController.php @@ -0,0 +1,44 @@ +name = $participant->first_name; $this->phone = formatToSwedenPrefix($participant->guardian_phone); + $this->smsContent = $smsContent; } /** @@ -68,7 +65,8 @@ class SmsMail extends Mailable public function content(): Content { return new Content( - view: 'mail.sms', + view: 'mail.sms', + with: ['smsContent' => $this->smsContent], ); } diff --git a/app/Models/EmailLog.php b/app/Models/EmailLog.php new file mode 100644 index 0000000..7aa023b --- /dev/null +++ b/app/Models/EmailLog.php @@ -0,0 +1,32 @@ +belongsTo(Participant::class); + } + + public function mailtemplate() + { + return $this->belongsTo(Mailtemplate::class); + } + + public function smstemplate() + { + return $this->belongsTo(Smstemplate::class); + } +} diff --git a/app/Models/Mailtemplate.php b/app/Models/Mailtemplate.php index 8d1a292..4f0fc99 100644 --- a/app/Models/Mailtemplate.php +++ b/app/Models/Mailtemplate.php @@ -10,6 +10,12 @@ class Mailtemplate extends Model 'title', 'content', 'type', - 'draft' + 'draft', + 'smstemplate_id', ]; + + public function smstemplate() + { + return $this->belongsTo(Smstemplate::class); + } } diff --git a/app/Models/Participant.php b/app/Models/Participant.php index 494420a..41e9cd6 100644 --- a/app/Models/Participant.php +++ b/app/Models/Participant.php @@ -29,6 +29,11 @@ class Participant extends Model 'ssn' ]; + public function emailLogs() + { + return $this->hasMany(EmailLog::class); + } + protected static function booted() { static::created(function ($post) { diff --git a/app/Models/Smstemplate.php b/app/Models/Smstemplate.php new file mode 100644 index 0000000..0fb2e90 --- /dev/null +++ b/app/Models/Smstemplate.php @@ -0,0 +1,15 @@ +colors([ 'primary' => Color::Amber, ]) + ->renderHook( + 'panels::head.end', + fn () => '', + ) + ->navigationGroups([ + \Filament\Navigation\NavigationGroup::make('Templates'), + \Filament\Navigation\NavigationGroup::make('Logs'), + ]) + ->brandName('vBytes LAN') + ->favicon(asset('images/vbytes-logo.png')) + ->brandLogo(asset('images/vbytes-logo.png')) + ->brandLogoHeight('5rem') ->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources') ->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages') ->pages([ diff --git a/database/migrations/2026_05_18_000000_create_smstemplates_table.php b/database/migrations/2026_05_18_000000_create_smstemplates_table.php new file mode 100644 index 0000000..8cefaf9 --- /dev/null +++ b/database/migrations/2026_05_18_000000_create_smstemplates_table.php @@ -0,0 +1,25 @@ +id(); + $table->string('title'); + $table->string('type'); + $table->longText('content'); + $table->boolean('draft')->default(false); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('smstemplates'); + } +}; diff --git a/database/migrations/2026_05_18_000001_make_type_nullable_in_smstemplates_table.php b/database/migrations/2026_05_18_000001_make_type_nullable_in_smstemplates_table.php new file mode 100644 index 0000000..67a2d0b --- /dev/null +++ b/database/migrations/2026_05_18_000001_make_type_nullable_in_smstemplates_table.php @@ -0,0 +1,22 @@ +string('type')->nullable()->change(); + }); + } + + public function down(): void + { + Schema::table('smstemplates', function (Blueprint $table) { + $table->string('type')->nullable(false)->change(); + }); + } +}; diff --git a/database/migrations/2026_05_18_000002_add_smstemplate_id_to_mailtemplates_table.php b/database/migrations/2026_05_18_000002_add_smstemplate_id_to_mailtemplates_table.php new file mode 100644 index 0000000..d596e83 --- /dev/null +++ b/database/migrations/2026_05_18_000002_add_smstemplate_id_to_mailtemplates_table.php @@ -0,0 +1,22 @@ +foreignId('smstemplate_id')->nullable()->constrained('smstemplates')->nullOnDelete()->after('draft'); + }); + } + + public function down(): void + { + Schema::table('mailtemplates', function (Blueprint $table) { + $table->dropForeignIdFor(\App\Models\Smstemplate::class); + }); + } +}; diff --git a/database/migrations/2026_05_18_000003_create_email_logs_table.php b/database/migrations/2026_05_18_000003_create_email_logs_table.php new file mode 100644 index 0000000..161a506 --- /dev/null +++ b/database/migrations/2026_05_18_000003_create_email_logs_table.php @@ -0,0 +1,26 @@ +id(); + $table->foreignId('participant_id')->constrained()->cascadeOnDelete(); + $table->integer('lan_id')->nullable(); + $table->string('guardian_email')->nullable(); + $table->foreignId('mailtemplate_id')->nullable()->constrained('mailtemplates')->nullOnDelete(); + $table->foreignId('smstemplate_id')->nullable()->constrained('smstemplates')->nullOnDelete(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('email_logs'); + } +}; diff --git a/database/migrations/2026_05_18_000004_add_error_to_email_logs_table.php b/database/migrations/2026_05_18_000004_add_error_to_email_logs_table.php new file mode 100644 index 0000000..c4928e8 --- /dev/null +++ b/database/migrations/2026_05_18_000004_add_error_to_email_logs_table.php @@ -0,0 +1,22 @@ +text('error')->nullable()->after('smstemplate_id'); + }); + } + + public function down(): void + { + Schema::table('email_logs', function (Blueprint $table) { + $table->dropColumn('error'); + }); + } +}; diff --git a/resources/views/mail/sms.blade.php b/resources/views/mail/sms.blade.php index 9e88152..de4964e 100644 --- a/resources/views/mail/sms.blade.php +++ b/resources/views/mail/sms.blade.php @@ -1,7 +1,2 @@ -Mejlutskick gällande LAN +{{ $smsContent }} -Vi vill med detta sms göra dig uppmärksam på att vi har skickat ett mejl till den e-postadress som angavs när ditt barn anmäldes till LAN. -Vi ber dig att läsa mejlet noggrant. I det framgår bland annat om ditt barn har fått en plats, vilken plats det är och hur du gör för att anmäla dig till att hjälpa till med evenemanget. -Om du har några funderingar, kontakta oss på vbyteslan@gmail.com. - -Med vänliga hälsningar, LAN-gruppen Vbytes \ No newline at end of file