Skip to content
142 changes: 142 additions & 0 deletions app-modules/bot-discord/src/SlashCommands/AddressCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php

declare(strict_types=1);

namespace He4rt\BotDiscord\SlashCommands;

use Discord\Parts\Interactions\Command\Option;
use Discord\Parts\Interactions\Interaction;
use Throwable;

class AddressCommand extends AbstractSlashCommand
{
private const array STATES = [
'AC' => 'Acre',
'AL' => 'Alagoas',
'AP' => 'Amapá',
'AM' => 'Amazonas',
'BA' => 'Bahia',
'CE' => 'Ceará',
'DF' => 'Distrito Federal',
'ES' => 'Espírito Santo',
'GO' => 'Goiás',
'MA' => 'Maranhão',
'MT' => 'Mato Grosso',
'MS' => 'Mato Grosso do Sul',
'MG' => 'Minas Gerais',
'PA' => 'Pará',
'PB' => 'Paraíba',
'PR' => 'Paraná',
'PE' => 'Pernambuco',
'PI' => 'Piauí',
'RJ' => 'Rio de Janeiro',
'RN' => 'Rio Grande do Norte',
'RS' => 'Rio Grande do Sul',
'RO' => 'Rondônia',
'RR' => 'Roraima',
'SC' => 'Santa Catarina',
'SP' => 'São Paulo',
'SE' => 'Sergipe',
'TO' => 'Tocantins',
];

protected $name = 'endereco';

protected $description = 'Defina sua localização (estado e cidade).';

/** @var array<mixed> */
protected $options = [];

/** @var array<mixed> */
protected $permissions = [];

protected $admin = false;

protected $hidden = false;

public function handle(Interaction $interaction): void
{
if (!$this->memberProvider?->user) {
$interaction->respondWithMessage(
'Você precisa se apresentar primeiro. Use o comando `/apresentar`.',
true
);

return;
}

try {
$state = mb_strtoupper((string) $this->value('estado'));
$city = $this->value('cidade');

if (!isset(self::STATES[$state])) {
$interaction->respondWithMessage('Estado inválido. Use a sigla (ex: SP, RJ).', true);

return;
}

$this->memberProvider->user->address()->updateOrCreate([], [
'country' => 'BRA',
'state' => $state,
'city' => $city,
]);

$stateName = self::STATES[$state];

$interaction->respondWithMessage(
sprintf('Localização atualizada para **%s, %s** 🇧🇷', $city, $stateName),
true
);
} catch (Throwable $throwable) {
$this->logger()->error('Error AddressCommand:', [$throwable->getMessage()]);

$interaction->respondWithMessage('Erro ao atualizar localização.', true);
}
}

/**
* @return array<mixed>
*/
public function options(): array
{
return [
[
'name' => 'estado',
'description' => 'Seu estado (UF)',
'type' => Option::STRING,
'required' => true,
'autocomplete' => true,
],
[
'name' => 'cidade',
'description' => 'Sua cidade',
'type' => Option::STRING,
'required' => true,
'max_length' => 100,
],
];
}

/**
* @return array<string, callable>
*/
public function autocomplete(): array
{
return [
'estado' => function (Interaction $interaction, ?string $value): array {
$states = collect(self::STATES)
->map(fn (string $name, string $uf): string => sprintf('%s - %s', $uf, $name));

if ($value) {
$search = mb_strtolower($value);
$states = $states->filter(
fn (string $label, string $uf): bool => str_contains(mb_strtolower($label), $search)
|| str_contains(mb_strtolower($uf), $search)
);
}

return $states->take(25)->all();
},
];
}
}
75 changes: 30 additions & 45 deletions app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
use Discord\Builders\Components\TextInput;
use Discord\Helpers\Collection;
use Discord\Parts\Interactions\Interaction;
use He4rt\Identity\User\Actions\UpdateProfile;
use He4rt\Identity\User\DTOs\UpdateProfileDTO;
use He4rt\Profile\Actions\UpsertProfile;
use He4rt\Profile\DTOs\UpsertProfileDTO;
use He4rt\Profile\Models\Profile;
use Illuminate\Support\Facades\Date;
use Throwable;

Expand Down Expand Up @@ -61,7 +62,12 @@ class EditProfileCommand extends AbstractSlashCommand
*/
public function handle(Interaction $interaction): void
{
if (!$this->memberProvider?->user?->information) {
$profile = Profile::query()
->where('user_id', $this->memberProvider?->user?->id)
->where('tenant_id', $this->memberProvider?->tenant_id)
->first();

if (!$profile) {
$interaction->respondWithMessage(
'Parece que você ainda não completou sua apresentação. Use o comando `/apresentar` para continuar.',
true
Expand All @@ -70,16 +76,14 @@ public function handle(Interaction $interaction): void
return;
}

$profile = $this->memberProvider->user->information;

$this->modal('Editar Perfil')
->components([
TextInput::new('Nome', TextInput::STYLE_SHORT)
->setCustomId('name')
->setMinLength(2)
->setMaxLength(32)
->setPlaceholder('Seu nome')
->setValue($profile->name ?? '')
->setValue($this->memberProvider->user->name ?? '')
->setRequired(true),

TextInput::new('Nickname', TextInput::STYLE_SHORT)
Expand All @@ -90,26 +94,10 @@ public function handle(Interaction $interaction): void
->setValue($profile->nickname ?? '')
->setRequired(true),

TextInput::new('Git/Github (Opcional)', TextInput::STYLE_SHORT)
->setCustomId('github_url')
->setMinLength(0)
->setMaxLength(60)
->setPlaceholder('https://github.com/...')
->setValue($profile->github_url ?? '')
->setRequired(false),

TextInput::new('Linkedin (Opcional)', TextInput::STYLE_SHORT)
->setCustomId('linkedin_url')
->setMinLength(0)
->setMaxLength(60)
->setPlaceholder('https://linkedin.com/in/...')
->setValue($profile->linkedin_url ?? '')
->setRequired(false),

TextInput::new('Nos conte um pouco sobre você', TextInput::STYLE_PARAGRAPH)
->setCustomId('about')
->setMinLength(5)
->setMaxLength(1000)
->setMaxLength(500)
->setPlaceholder('Fale mais sobre você...')
->setValue($profile->about ?? '')
->setRequired(true),
Expand All @@ -130,37 +118,34 @@ private function persistData(
Collection $components
): void {
try {
$payload = UpdateProfileDTO::fromPayload([
'tenant_id' => $this->memberProvider->tenant_id,
'provider' => $this->memberProvider->provider,
'external_account_id' => $interaction->user->id,
'name' => $components->get('custom_id', 'name')?->value,
'nickname' => $components->get('custom_id', 'nickname')?->value,
'linkedin_url' => $components->get('custom_id', 'linkedin_url')?->value,
'github_url' => $components->get('custom_id', 'github_url')?->value,
'birthdate' => $components->get('custom_id', 'birthdate')?->value,
'about' => $components->get('custom_id', 'about')?->value,
$name = $components->get('custom_id', 'name')?->value;
$nickname = $components->get('custom_id', 'nickname')?->value;
$about = $components->get('custom_id', 'about')?->value;

$this->memberProvider->user->update(['name' => $name]);

$profile = Profile::query()
->where('user_id', $this->memberProvider->user->id)
->where('tenant_id', $this->memberProvider->tenant_id)
->firstOrFail();

$dto = UpsertProfileDTO::fromArray([
'nickname' => $nickname,
'about' => $about,
]);

resolve(UpdateProfile::class)->handle($payload);
resolve(UpsertProfile::class)->handle($profile, $dto);

$this
->message('Perfil atualizado!')
->content('https://heartdevs.com/')
->color('800080')
->title('Perfil '.$payload->nickname)
->title('Perfil '.$nickname)
->thumbnailUrl($interaction->user->avatar)
->fields([ // max 3 fields per row
'Nome/Nickname' => $payload->nickname,
'Sobre' => $payload->about,
->fields([
'Nome/Nickname' => $nickname,
'Sobre' => $about,
])
->fields(
[ // max 3 fields per row
'Git/Github' => $payload->githubUrl ?? '-',
'Linkedin' => $payload->linkedinUrl ?? '-',
],
inline: false
)
->footerIcon($interaction->guild->icon)
->footerText(Date::now()->format('Y').' © He4rt Developers')
->timestamp(now())
Expand Down
57 changes: 23 additions & 34 deletions app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
use He4rt\Identity\ExternalIdentity\DTOs\ResolveUserProviderDTO;
use He4rt\Identity\ExternalIdentity\Models\ExternalIdentity;
use He4rt\Identity\Tenant\Models\Tenant;
use He4rt\Identity\User\Actions\InformationUserAction;
use He4rt\Identity\User\Actions\ResolveUserContext;
use He4rt\Identity\User\DTOs\UpsertInformationDTO;
use He4rt\Identity\User\Models\User;
use He4rt\Profile\Actions\UpsertProfile;
use He4rt\Profile\DTOs\UpsertProfileDTO;
use He4rt\Profile\Models\Profile;
use Illuminate\Support\Facades\Date;
use Laracord\Commands\SlashCommand;
use Throwable;
Expand Down Expand Up @@ -75,24 +76,10 @@ public function handle(Interaction $interaction): void
->setPlaceholder('Fulano123')
->setRequired(true),

TextInput::new('Git/Github (Opcional)', TextInput::STYLE_SHORT)
->setCustomId('github_url')
->setMinLength(0)
->setMaxLength(60)
->setPlaceholder('https://github.com/YOUR_USERNAME')
->setRequired(false),

TextInput::new('LinkedIn (Opcional)', TextInput::STYLE_SHORT)
->setCustomId('linkedin_url')
->setMinLength(0)
->setMaxLength(60)
->setPlaceholder('https://linkedin.com/in/YOUR_USERNAME')
->setRequired(false),

TextInput::new('Nos conte um pouco sobre você', TextInput::STYLE_PARAGRAPH)
->setCustomId('about')
->setMinLength(5)
->setMaxLength(1000)
->setMaxLength(500)
->setPlaceholder('Entrei de curioso e acabei gostando do servidor!')
->setRequired(true),

Expand Down Expand Up @@ -135,35 +122,37 @@ private function persistData(Interaction $interaction, Collection $components):

$userContext = resolve(ResolveUserContext::class)->handle($userDto);

$informationDto = UpsertInformationDTO::make([
'user' => $userContext->user,
'name' => $components->get('custom_id', 'name')->value,
'nickname' => $components->get('custom_id', 'nickname')->value,
'about' => $components->get('custom_id', 'about')->value,
'linkedin_url' => $components->get('custom_id', 'linkedin_url')?->value,
'github_url' => $components->get('custom_id', 'github_url')?->value,
'birthdate' => null,
$name = $components->get('custom_id', 'name')->value;
$nickname = $components->get('custom_id', 'nickname')->value;
$about = $components->get('custom_id', 'about')->value;

$userContext->user->update(['name' => $name]);

$profile = Profile::query()
->where('user_id', $userContext->user->id)
->where('tenant_id', $tenantProvider->tenant_id)
->firstOrFail();

$dto = UpsertProfileDTO::fromArray([
'nickname' => $nickname,
'about' => $about,
]);

$userInformation = resolve(InformationUserAction::class)->handle($informationDto);
resolve(UpsertProfile::class)->handle($profile, $dto);

$this
->message('Nova apresentação')
->title('Apresentação de '.$userInformation->nickname)
->title('Apresentação de '.$nickname)
->thumbnailUrl($interaction->user->avatar)
->content(sprintf(
'<@%s> acabou de se apresentar na comunidade.',
$interaction->user->id
))
->fields([
'Nome' => $userInformation->name,
'Nickname' => $userInformation->nickname,
])
->fields(['Sobre' => $userInformation->about], inline: false)
->fields([
'GitHub' => $userInformation->github_url ?? '-',
'LinkedIn' => $userInformation->linkedin_url ?? '-',
'Nome' => $name,
'Nickname' => $nickname,
])
->fields(['Sobre' => $about], inline: false)
->footerIcon($interaction->guild->icon)
->footerText(Date::now()->format('Y').' © He4rt Developers')
->timestamp(now())
Expand Down
Loading