Skip to content

Commit

Permalink
Merge pull request #6 from romo4ko/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
romo4ko authored Oct 27, 2024
2 parents ab412ed + facc2f1 commit 6efa523
Show file tree
Hide file tree
Showing 18 changed files with 354 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,5 @@ VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

TELEGRAM_BOT_TOKEN=
TELEGRAM_SECRET_KEY=

FRONTEND_URL=https://localhost:3000
16 changes: 16 additions & 0 deletions app/DTO/Api/Challenge/Request/ChallengeFilterDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\DTO\Api\Challenge\Request;

use App\Models\Enums\Challenge\ChallengeType;
use Spatie\LaravelData\Data;

class ChallengeFilterDTO extends Data
{
public function __construct(
public ?ChallengeType $challengeType,
public ?string $startDate,
public ?string $endDate,
){
}
}
27 changes: 27 additions & 0 deletions app/DTO/Api/Challenge/Response/ChallengeShowDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace App\DTO\Api\Challenge\Response;

use App\Models\Challenge;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Spatie\LaravelData\Data;

class ChallengeShowDTO extends Data
{
public function __construct(
public Challenge $challenge,
public Collection $members,
) {
}

public static function fromModel(Challenge $challenge): self
{
return new self(
$challenge,
$challenge->users()->get(),
);
}
}
23 changes: 23 additions & 0 deletions app/DTO/Api/User/Response/UserShowDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\DTO\Api\User\Response;

use App\Models\User;
use Spatie\LaravelData\Data;

class UserShowDTO extends Data
{
public function __construct(
public User $user,
public bool $isEditor
){
}

public static function fromModel(User $user): self
{
return new self(
$user,
$user->id === auth()->id()
);
}
}
30 changes: 30 additions & 0 deletions app/DTO/Api/User/Response/UserTeamIsCaptainDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace App\DTO\Api\User\Response;

use App\Models\Team;
use Illuminate\Database\Eloquent\Collection;
use Spatie\LaravelData\Data;

class UserTeamIsCaptainDTO extends Data
{
public function __construct(
public int $id,
public ?string $image,
public string $name,
public ?int $countMembers
) {
}

public static function fromModal(Team $team): self
{
return new self(
$team->id,
$team->image,
$team->name,
$team->users->count(),
);
}
}
14 changes: 14 additions & 0 deletions app/Filament/Pages/Dashboard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Filament\Pages;

use Filament\Pages\BasePage;
use Filament\Panel;

class Dashboard extends BasePage
{
public function panel(Panel $panel): Panel
{
return $panel->pages([]);
}
}
11 changes: 8 additions & 3 deletions app/Filament/Resources/ChallengeResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,26 @@ public static function form(Form $form): Form
])
->disabled(
function ($record) {
if ($record === null) {
return false;
}
return $record->teams->count() > 0 || $record->users->count() > 0;
}
)
->required()
->maxWidth('sm'),
Forms\Components\Textarea::make('description')
->label('Описание')
->required()
->rows(5),
Forms\Components\Section::make()->schema([
DateTimePicker::make('start_date')
->label('Дата начала')
->required()
->default(now()),
DateTimePicker::make('end_date')
->label('Дата окончания')
->nullable(),
->required(),
])->columns(),
Forms\Components\Textarea::make('result')
->label('Результаты завершения челленджа')
Expand All @@ -84,7 +89,7 @@ function ($record) {
->visibility('public')
->maxWidth('xs')
->label('Изображение'),
Forms\Components\Section::make()
$record !== null ? Forms\Components\Section::make()
->schema([
$record->type === ChallengeType::PERSONAL->value ? Forms\Components\Select::make( 'users')
->label('Участники челленджа')
Expand All @@ -96,7 +101,7 @@ function ($record) {
->relationship('teams', 'name')
->preload()
->multiple(),
])->columns(2),
])->columns(2) : new Forms\Components\Section(),
])->columns(1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace App\Filament\Resources\ChallengeResource\Pages;

use App\Filament\Resources\ChallengeResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;

class CreateChallenge extends CreateRecord
Expand Down
14 changes: 14 additions & 0 deletions app/Filament/Resources/ChallengeResource/Pages/EditChallenge.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Filament\Resources\ChallengeResource\Pages;

use App\Filament\Resources\ChallengeResource;
use App\Http\Controllers\Api\TelegramController;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

Expand All @@ -19,6 +20,19 @@ protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
Actions\Action::make('Отправить уведомления')
->action('sendNotification')
->color('success'),
];
}

public function sendNotification(TelegramController $controller): void
{
$record = $this->form->getRecord();

$url = env('FRONTEND_URL') . "/challenges/{$record->id}";
$message = "Создан новый челлендж: {$record->name}! \nСкорее присоединяйся по ссылке {$url}";

$controller->sendMessageForAll($message);
}
}
51 changes: 51 additions & 0 deletions app/Filament/Widgets/StatsOverview.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace App\Filament\Widgets;

use App\Models\User;
use Carbon\Carbon;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
use Illuminate\Support\Facades\DB;

class StatsOverview extends BaseWidget
{
protected function getStats(): array
{
return [
Stat::make('Новых пользователей за этот месяц',
User::query()->where('created_at', '>=', Carbon::now()->startOfMonth())->count())
->chart(self::getCountUsersRegisteredForLastMonth())
->color('success'),
Stat::make(
'Активных пользователей',
User::query()->where('is_confirmed', true)->count()
),
Stat::make(
'Всего пользователей',
User::query()->count()
),
];
}

private function getCountUsersRegisteredForLastMonth(): array
{
$results = [];
$startTime = Carbon::now()->startOfMonth();
$daysLeft = $startTime->diffInDays(Carbon::now());

for ($i = 0; $i < $daysLeft; $i++) {
$endTime = $startTime->copy()->addDay();
$count = DB::table('users')
->whereBetween('created_at', [
$startTime,
$endTime,
])
->count();
$results[] = $count;
$startTime = $endTime;
}

return $results;
}
}
37 changes: 37 additions & 0 deletions app/Http/Controllers/Api/ChallengeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace App\Http\Controllers\Api;

use App\DTO\Api\Challenge\Request\ChallengeFilterDTO;
use App\Models\Challenge;
use App\Services\Api\ChallengeService;

class ChallengeController extends Controller
{
public function __construct(
protected ChallengeService $challengeService
){
}

public function index(ChallengeFilterDTO $challengeFilterDTO): array
{
return $this->challengeService->index($challengeFilterDTO);
}

public function show(int $id): array
{
$challenge = Challenge::query()->findOrFail($id);

return $this->challengeService->show($challenge);
}

public function joinPersonal(): array
{
return [];
}

public function joinTeam(): array
{
return [];
}
}
30 changes: 30 additions & 0 deletions app/Http/Controllers/Api/TelegramController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,34 @@ public function syncTelegram(Request $request): JsonResponse
return response()->json(['message' => 'error'], 404);
}
}

public function sendMessageForAll(string $message)
{
$users = User::query()
->whereNotNull('telegram_id')
->get();

foreach ($users as $user) {
$this->sendMessage($user->telegram_id, $message);
}
}

public function sendMessage(string $telegramId, string $message)
{
$ch = curl_init();
curl_setopt_array(
$ch,
array(
CURLOPT_URL => 'https://api.telegram.org/bot' . env('TELEGRAM_BOT_TOKEN') . '/sendMessage',
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 10,
CURLOPT_POSTFIELDS => array(
'chat_id' => $telegramId,
'text' => $message,
),
)
);
curl_exec($ch);
}
}
11 changes: 10 additions & 1 deletion app/Http/Controllers/Api/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,18 @@ public function __construct(
) {
}

public function teamIsCaptain(int $id): array
{
$teams = User::query()->findOrFail($id);

return $this->userService->teamIsCaptain($teams);
}

public function show(int $id): array
{
return User::query()->findOrFail($id)?->toArray();
$user = User::query()->findOrFail($id);

return $this->userService->show($user);
}

public function update(int $id, UserUpdateDTO $userUpdateDTO): array|JsonResponse
Expand Down
34 changes: 34 additions & 0 deletions app/Services/Api/ChallengeService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace App\Services\Api;

use App\DTO\Api\Challenge\Request\ChallengeFilterDTO;
use App\DTO\Api\Challenge\Response\ChallengeShowDTO;
use App\Models\Challenge;
use Illuminate\Database\Eloquent\Builder;

class ChallengeService
{
public function index(ChallengeFilterDTO $challengeFilterDTO): array
{
$games = Challenge::query()
->when($challengeFilterDTO->challengeType, function (Builder $query) use ($challengeFilterDTO) {
$query->where('type', '=', $challengeFilterDTO->challengeType->value);
})
->when($challengeFilterDTO->startDate, function (Builder $query) use ($challengeFilterDTO) {
$query->where('start_date', '>=', $challengeFilterDTO->startDate);
})
->when($challengeFilterDTO->endDate, function (Builder $query) use ($challengeFilterDTO) {
$query->where('end_date', '<=', $challengeFilterDTO->endDate);
})
->orderBy('end_date', 'desc')
->get();

return $games->toArray();
}

public function show(Challenge $challenge): array
{
return ChallengeShowDTO::from($challenge)->toArray();
}
}
Loading

0 comments on commit 6efa523

Please sign in to comment.