Skip to content

Commit 6887906

Browse files
authored
Merge pull request #3487 from codeeu/dev
dev
2 parents 6a23846 + 385a6fa commit 6887906

6 files changed

Lines changed: 126 additions & 3 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use App\Jobs\ProcessUserDeletion;
6+
use App\User;
7+
use Illuminate\Console\Command;
8+
use Throwable;
9+
10+
class DeleteUserAccount extends Command
11+
{
12+
protected $signature = 'users:delete-account
13+
{email : The email address of the account to delete}
14+
{--dry-run : Show what would be deleted without deleting}
15+
{--queue : Dispatch deletion through the queue instead of running immediately}
16+
{--force : Skip confirmation prompt}';
17+
18+
protected $description = 'Delete a user account by email and reassign related event ownership to the legacy user.';
19+
20+
public function handle(): int
21+
{
22+
$email = mb_strtolower(trim((string) $this->argument('email')));
23+
24+
/** @var User|null $user */
25+
$user = User::withTrashed()
26+
->whereRaw('LOWER(email) = ?', [$email])
27+
->first();
28+
29+
if (!$user) {
30+
$this->error("No user found for email: {$email}");
31+
return self::FAILURE;
32+
}
33+
34+
$this->info("Found user #{$user->id}: {$user->firstname} {$user->lastname} <{$user->email}>");
35+
36+
if ($this->option('dry-run')) {
37+
$this->line('Dry run enabled. No changes were made.');
38+
return self::SUCCESS;
39+
}
40+
41+
if (!$this->option('force')) {
42+
$confirmed = $this->confirm(
43+
"This will permanently delete user #{$user->id} ({$user->email}). Continue?",
44+
false
45+
);
46+
47+
if (!$confirmed) {
48+
$this->line('Cancelled.');
49+
return self::SUCCESS;
50+
}
51+
}
52+
53+
try {
54+
if ($this->option('queue')) {
55+
ProcessUserDeletion::dispatch($user->id);
56+
$this->info("Deletion job dispatched for user #{$user->id}.");
57+
return self::SUCCESS;
58+
}
59+
60+
// Execute immediately for urgent/account-support requests.
61+
(new ProcessUserDeletion($user->id))->handle();
62+
$this->info("User #{$user->id} has been deleted.");
63+
64+
return self::SUCCESS;
65+
} catch (Throwable $e) {
66+
$this->error("Failed to delete user #{$user->id}: {$e->getMessage()}");
67+
return self::FAILURE;
68+
}
69+
}
70+
}

app/HackathonsPage.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class HackathonsPage extends Model
1212
'dynamic_content',
1313
'hero_title',
1414
'hero_subtitle',
15+
'hero_background_image_url',
1516
'intro_title',
1617
'intro_paragraph_1',
1718
'intro_paragraph_2',
@@ -21,6 +22,7 @@ class HackathonsPage extends Model
2122
'details_paragraph_3',
2223
'details_paragraph_4',
2324
'video_url',
25+
'video_poster_image_url',
2426
'extra_button_text',
2527
'extra_button_link',
2628
'recap_button_text',

app/Nova/HackathonsPage.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public function fields(Request $request): array
4949
Panel::make('Hero', [
5050
Text::make('Hero title', 'hero_title')->nullable(),
5151
Trix::make('Hero subtitle', 'hero_subtitle')->nullable(),
52+
Text::make('Hero background image URL', 'hero_background_image_url')
53+
->nullable()
54+
->help('Optional. Use a relative path like /images/hackathons/hackathons_bg.png or a full URL.'),
5255
])->collapsable()->collapsedByDefault(),
5356

5457
Panel::make('Intro section', [
@@ -64,6 +67,9 @@ public function fields(Request $request): array
6467
Trix::make('Details paragraph 3', 'details_paragraph_3')->nullable(),
6568
Trix::make('Details paragraph 4', 'details_paragraph_4')->nullable(),
6669
Text::make('Video URL (embed)', 'video_url')->nullable(),
70+
Text::make('Video poster image URL', 'video_poster_image_url')
71+
->nullable()
72+
->help('Optional. Image shown behind the play button. Use a relative path like /images/Visual%20for%20EU%20Finals%20webpage.png or a full URL.'),
6773
Text::make('Extra button text (optional)', 'extra_button_text')->nullable(),
6874
Text::make('Extra button link (optional)', 'extra_button_link')->nullable(),
6975
Text::make('Recap button text', 'recap_button_text')->nullable(),
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration {
8+
public function up(): void
9+
{
10+
if (Schema::hasTable('hackathons_page') && !Schema::hasColumn('hackathons_page', 'hero_background_image_url')) {
11+
Schema::table('hackathons_page', function (Blueprint $table) {
12+
$table->string('hero_background_image_url')->nullable()->after('hero_subtitle');
13+
});
14+
}
15+
16+
if (Schema::hasTable('hackathons_page') && !Schema::hasColumn('hackathons_page', 'video_poster_image_url')) {
17+
Schema::table('hackathons_page', function (Blueprint $table) {
18+
$table->string('video_poster_image_url')->nullable()->after('video_url');
19+
});
20+
}
21+
}
22+
23+
public function down(): void
24+
{
25+
if (Schema::hasTable('hackathons_page') && Schema::hasColumn('hackathons_page', 'video_poster_image_url')) {
26+
Schema::table('hackathons_page', function (Blueprint $table) {
27+
$table->dropColumn('video_poster_image_url');
28+
});
29+
}
30+
31+
if (Schema::hasTable('hackathons_page') && Schema::hasColumn('hackathons_page', 'hero_background_image_url')) {
32+
Schema::table('hackathons_page', function (Blueprint $table) {
33+
$table->dropColumn('hero_background_image_url');
34+
});
35+
}
36+
}
37+
};
38+
3.17 MB
Loading

resources/views/hackathons/index.blade.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
$hasHackathonsPageTable = \Illuminate\Support\Facades\Schema::hasTable('hackathons_page');
1010
$page = $hasHackathonsPageTable ? \App\HackathonsPage::config() : null;
1111
$dynamic = $page && $page->dynamic_content;
12+
13+
$defaultHeroBackground = '/images/hackathons/hackathons_bg.png';
14+
$heroBackground = ($dynamic && $page && $page->hero_background_image_url) ? $page->hero_background_image_url : $defaultHeroBackground;
15+
16+
// Note: file on disk has spaces; URL must be encoded.
17+
$defaultVideoPoster = '/images/Visual%20for%20EU%20Finals%20webpage.png';
18+
$videoPoster = ($dynamic && $page && $page->video_poster_image_url) ? $page->video_poster_image_url : $defaultVideoPoster;
1219
@endphp
1320

1421
@section('layout.breadcrumb')
@@ -46,13 +53,13 @@
4653
<img
4754
class="absolute top-0 -left-1/4 w-[150vw] !max-w-none md:hidden"
4855
loading="lazy"
49-
src="/images/hackathons/hackathons_bg.png"
56+
src="{{ $heroBackground }}"
5057
style="clip-path: ellipse(71% 73% at 40% 20%);"
5158
/>
5259
<img
5360
class="absolute top-0 right-0 h-full max-w-[calc(70vw)] object-cover hidden md:block"
5461
loading="lazy"
55-
src="/images/hackathons/hackathons_bg.png"
62+
src="{{ $heroBackground }}"
5663
style="clip-path: ellipse(70% 140% at 70% 25%);"
5764
/>
5865
</div>
@@ -105,7 +112,7 @@ class="animation-element move-background duration-[1.5s] absolute z-0 lg:-bottom
105112
<div class="relative pt-20 pb-16 codeweek-container-lg md:pt-40 md:pb-28">
106113
<div class="flex flex-col gap-6 lg:flex-row lg:gap-20">
107114
<div class="flex overflow-hidden relative flex-1 items-center">
108-
<img src="{{asset('images/hackathons/hackathon.png')}}" class="object-cover h-full rounded-lg">
115+
<img src="{{ $videoPoster }}" class="object-cover h-full rounded-lg">
109116
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
110117
@include('layout.video-player', [
111118
'id' => 'hackathons-video',

0 commit comments

Comments
 (0)