Skip to content

Commit f85dcad

Browse files
feat: [LAR-22] update sponsoring page (#268)
2 parents 79afcef + 0185cb7 commit f85dcad

26 files changed

+460
-695
lines changed

.env.example

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ MAIL_PASSWORD=null
3636
MAIL_ENCRYPTION=null
3737
MAIL_FROM_ADDRESS=no-reply@laravel.cm
3838
MAIL_FROM_NAME="${APP_NAME}"
39+
MAIL_SUPPORT=mail-support@laravel.cm
3940

4041
MAILGUN_DOMAIN=
4142
MAILGUN_SECRET=
@@ -57,11 +58,6 @@ GITHUB_CLIENT_ID=
5758
GITHUB_CLIENT_SECRET=
5859
GITHUB_REDIRECT=${APP_URL}/auth/github/callback
5960

60-
SLACK_WEBHOOK_URL=
61-
SLACK_TEAM_NAME="Laravel Cameroun"
62-
SLACK_API_TOKEN=
63-
SLACK_TEAM_URL="https://laravelcm.slack.com"
64-
6561
MARKDOWNX_GIPHY_API_KEY=
6662
TORCHLIGHT_TOKEN=
6763
TORCHLIGHT_THEME=moonlight-ii

app/Http/Controllers/SponsoringController.php

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Livewire\Components;
6+
7+
use App\Enums\PaymentType;
8+
use App\Enums\TransactionType;
9+
use App\Models\Transaction;
10+
use App\Models\User;
11+
use Filament\Forms;
12+
use Filament\Forms\Concerns\InteractsWithForms;
13+
use Filament\Forms\Contracts\HasForms;
14+
use Filament\Forms\Form;
15+
use Filament\Notifications\Notification;
16+
use Illuminate\Contracts\View\View;
17+
use Illuminate\Support\Facades\Auth;
18+
use Illuminate\Support\Facades\Cache;
19+
use Illuminate\Support\Facades\Log;
20+
use Livewire\Component;
21+
use NotchPay\Exceptions\ApiException;
22+
use NotchPay\NotchPay;
23+
use NotchPay\Payment;
24+
25+
/**
26+
* @property-read Form $form
27+
*/
28+
final class SponsorSubscription extends Component implements HasForms
29+
{
30+
use InteractsWithForms;
31+
32+
public ?array $data = [];
33+
34+
public function mount(): void
35+
{
36+
$auth = Auth::user();
37+
38+
$this->form->fill([
39+
'email' => $auth?->email,
40+
'name' => $auth?->name,
41+
'website' => $auth?->website,
42+
'profile' => 'developer',
43+
'currency' => 'xaf',
44+
]);
45+
}
46+
47+
public function form(Form $form): Form
48+
{
49+
return $form
50+
->schema([
51+
Forms\Components\TextInput::make('name')
52+
->label(__('validation.attributes.name'))
53+
->minLength(5)
54+
->required(),
55+
Forms\Components\TextInput::make('email')
56+
->label(__('validation.attributes.email'))
57+
->email()
58+
->required(),
59+
Forms\Components\ToggleButtons::make('profile')
60+
->label(__('pages/sponsoring.sponsor_form.profile'))
61+
->options([
62+
'developer' => __('validation.attributes.freelance'),
63+
'company' => __('validation.attributes.company'),
64+
])
65+
->icons([
66+
'developer' => 'phosphor-dev-to-logo-duotone',
67+
'company' => 'phosphor-buildings-duotone',
68+
])
69+
->grouped(),
70+
Forms\Components\TextInput::make('website')
71+
->label(__('global.website'))
72+
->prefixIcon('heroicon-m-globe-alt')
73+
->url(),
74+
Forms\Components\Group::make()
75+
->schema([
76+
Forms\Components\Select::make('currency')
77+
->label(__('validation.attributes.currency'))
78+
->live()
79+
->native()
80+
->options([
81+
'xaf' => 'XAF',
82+
'eur' => 'EUR',
83+
'usd' => 'USD',
84+
]),
85+
Forms\Components\TextInput::make('amount')
86+
->label(__('validation.attributes.amount'))
87+
->integer()
88+
->required()
89+
->afterStateUpdated(fn (?int $state) => $state ? abs($state) : 0)
90+
->prefix(fn (Forms\Get $get) => match ($get('currency')) {
91+
'usd' => '$',
92+
default => null
93+
})
94+
->suffix(fn (Forms\Get $get) => match ($get('currency')) {
95+
'eur' => '',
96+
'xaf' => 'FCFA',
97+
default => null,
98+
})
99+
->columnSpan(3),
100+
])
101+
->columns(4)
102+
->columnSpanFull(),
103+
])
104+
->statePath('data')
105+
->columns();
106+
}
107+
108+
public function submit(): void
109+
{
110+
$this->validate();
111+
112+
$email = data_get($this->form->getState(), 'email');
113+
$amount = data_get($this->form->getState(), 'amount');
114+
115+
/** @var User $user */
116+
$user = Auth::check() ? Auth::user() : User::findByEmailAddress(config('lcm.support_email'));
117+
118+
NotchPay::setApiKey(apiKey: config('lcm.notch-pay-public-token'));
119+
120+
try {
121+
$payload = Payment::initialize([
122+
'amount' => $amount,
123+
'email' => $email,
124+
'name' => data_get($this->form->getState(), 'name'),
125+
'currency' => data_get($this->form->getState(), 'currency'),
126+
'reference' => $user->id.'-'.$user->username().'-'.uniqid(),
127+
'callback' => route('notchpay-callback'),
128+
'description' => __('Soutien de la communauté Laravel & PHP Cameroun.'),
129+
]);
130+
131+
Transaction::query()->create([
132+
'amount' => $amount,
133+
'status' => $payload->transaction->status,
134+
'transaction_reference' => $payload->transaction->reference,
135+
'user_id' => $user->id,
136+
'fees' => $payload->transaction->fee,
137+
'type' => TransactionType::ONETIME->value,
138+
'metadata' => [
139+
'currency' => $payload->transaction->currency,
140+
'reference' => $payload->transaction->reference,
141+
'merchant' => [
142+
'reference' => $payload->transaction->merchant_reference,
143+
'customer' => $payload->transaction->customer,
144+
'laravel_cm_id' => Auth::id() ?? null,
145+
'profile' => data_get($this->form->getState(), 'profile'),
146+
],
147+
'initiated_at' => $payload->transaction->created_at,
148+
'description' => $payload->transaction->description,
149+
'for' => PaymentType::SPONSORING->value,
150+
],
151+
]);
152+
153+
$this->redirect($payload->authorization_url); // @phpstan-ignore-line
154+
} catch (ApiException $e) {
155+
Log::error($e->getMessage());
156+
157+
Notification::make()
158+
->title(__('notifications.sponsor_error_title'))
159+
->body(__('notifications.sponsor_error_body'))
160+
->danger()
161+
->send();
162+
}
163+
}
164+
165+
public function render(): View
166+
{
167+
return view('livewire.components.sponsor-subscription', [
168+
'sponsors' => Cache::remember(
169+
key: 'sponsors',
170+
ttl: now()->addWeek(),
171+
callback: fn () => Transaction::with(['user', 'user.media'])
172+
->scopes('complete')
173+
->distinct()
174+
->get(['id', 'user_id', 'metadata'])
175+
),
176+
]);
177+
}
178+
}

app/Livewire/Modals/AnonymousSponsors.php

Lines changed: 0 additions & 116 deletions
This file was deleted.

app/Livewire/Pages/Sponsoring.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Livewire\Pages;
6+
7+
use Illuminate\Contracts\View\View;
8+
use Livewire\Component;
9+
10+
final class Sponsoring extends Component
11+
{
12+
public function render(): View
13+
{
14+
return view('livewire.pages.sponsoring')->title(__('pages/sponsoring.title'));
15+
}
16+
}

0 commit comments

Comments
 (0)