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