Compare commits

...

5 Commits

Author SHA1 Message Date
156d8a9f68
Added middleware IsWebsiteTranslations and IsProject.
This fixes errors where Project or WebsiteTranslations are not found.
2024-05-03 00:06:59 +05:00
478cbe4762
Refactoring. 2024-05-03 00:03:35 +05:00
35c2368ae2
In the admin panel in the feedback section I added a date. 2024-05-03 00:01:39 +05:00
303af6f203
Fixed menu width. 2024-05-03 00:00:18 +05:00
1485180e20
Updated the captcha service to 0.8.1. 2024-05-02 23:59:38 +05:00
14 changed files with 189 additions and 14 deletions

View File

@ -1,5 +1,6 @@
DOCKER_APP_PORT=8080 DOCKER_APP_PORT=8080
DOCKER_CAPTCHA_PORT=8081 DOCKER_CAPTCHA_PORT=8081
DOCKER_CAPTCHA_WEBSOCKET_PORT=8082
DOCKER_DB_PORT=3306 DOCKER_DB_PORT=3306
MYSQL_ROOT_PASSWORD=root_pass MYSQL_ROOT_PASSWORD=root_pass
DB_DATABASE=my-projetcs DB_DATABASE=my-projetcs

View File

@ -3,7 +3,6 @@
namespace App\Http\Controllers\Site; namespace App\Http\Controllers\Site;
use App\Http\Requests\Site\Feedback\SendRequest; use App\Http\Requests\Site\Feedback\SendRequest;
use App\Models\ProjectFeedback;
use App\Services\Site\FeedbackService; use App\Services\Site\FeedbackService;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;

View File

@ -16,7 +16,6 @@ public function index(Request $request): View
{ {
$user = $request->user(); $user = $request->user();
$project = $request->get('project'); $project = $request->get('project');
$websiteTranslations = $request->get('websiteTranslations');
if (\is_null($project)) { if (\is_null($project)) {
$with = ['storage']; $with = ['storage'];
@ -28,7 +27,8 @@ public function index(Request $request): View
return \view('site.projects.index', $result->getData()); return \view('site.projects.index', $result->getData());
} }
$result = $this->projectService->getAboutByProject($project, $websiteTranslations, $request->user()); $websiteTranslations = $request->get('websiteTranslations');
$result = $this->projectService->getAboutByProject($project, $websiteTranslations, $user);
if ($result->isError()) { if ($result->isError()) {
$this->errors($result); $this->errors($result);
} }

View File

@ -0,0 +1,25 @@
<?php declare(strict_types=1);
namespace App\Http\Middleware;
use App\Models\Project;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
final class IsProject
{
public function handle(Request $request, \Closure $next): Response
{
$project = $request->get('project');
if (\is_null($project)) {
\abort(Response::HTTP_NOT_FOUND);
}
if ($project instanceof Project === false) {
\report("$project must be an instance of Project");
\abort(Response::HTTP_NOT_FOUND);
}
return $next($request);
}
}

View File

@ -0,0 +1,25 @@
<?php declare(strict_types=1);
namespace App\Http\Middleware;
use App\Services\WebsiteTranslations;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
final class IsWebsiteTranslations
{
public function handle(Request $request, \Closure $next): Response
{
$websiteTranslations = $request->get('websiteTranslations');
if (\is_null($websiteTranslations)) {
\abort(Response::HTTP_NOT_FOUND);
}
if ($websiteTranslations instanceof WebsiteTranslations === false) {
\report("$websiteTranslations must be an instance of WebsiteTranslations");
\abort(Response::HTTP_NOT_FOUND);
}
return $next($request);
}
}

View File

@ -7,7 +7,7 @@
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Closure; use Closure;
class ProjectAndLanguage extends ProjectLanguage final class ProjectAndLanguage extends ProjectLanguage
{ {
public function handle(Request $request, Closure $next): Response public function handle(Request $request, Closure $next): Response
{ {

View File

@ -242,6 +242,9 @@ body.mobile-menu-open {
#mobile-menu { #mobile-menu {
display: none; display: none;
} }
.wrapper .section-container {
flex: auto;
}
.main-container { .main-container {
flex-direction: row; flex-direction: row;
} }
@ -255,6 +258,7 @@ body.mobile-menu-open {
padding: 7px 10px 7px 0; padding: 7px 10px 7px 0;
} }
#menu { #menu {
flex: none;
background: #eee; background: #eee;
display: block; display: block;
width: 175px; width: 175px;

View File

@ -8,6 +8,7 @@
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
<th class="border-0">{{ __('admin-sections.Project') }}</th> <th class="border-0">{{ __('admin-sections.Project') }}</th>
<th class="border-0">{{ __('validation.attributes.date') }}</th>
<th class="border-0" style="width: 100%;">{{ __('site.attributes.message') }}</th> <th class="border-0" style="width: 100%;">{{ __('site.attributes.message') }}</th>
<th class="border-0">{{ __('site.attributes.name') }}</th> <th class="border-0">{{ __('site.attributes.name') }}</th>
<th class="border-0">{{ __('site.attributes.email') }}</th> <th class="border-0">{{ __('site.attributes.email') }}</th>
@ -17,6 +18,9 @@
@foreach($feedbacks as $feedback) @foreach($feedbacks as $feedback)
<tr> <tr>
<td>{{ $feedback->project->name }}</td> <td>{{ $feedback->project->name }}</td>
<td data-bs-toggle="tooltip" data-bs-placement="top" title="{{ $feedback->created_at->timezone(\App\Helpers\Helpers::getUserTimeZone())->isoFormat('LLL') }}">
{{ $feedback->created_at->diffForHumans() }}
</td>
<td>{!! $feedback->message !!}</td> <td>{!! $feedback->message !!}</td>
<td> <td>
<p>{{ $feedback->name }}</p> <p>{{ $feedback->name }}</p>

View File

@ -8,6 +8,7 @@
<table class="table table-centered table-nowrap mb-0 rounded"> <table class="table table-centered table-nowrap mb-0 rounded">
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
<th class="border-0">{{ __('validation.attributes.date') }}</th>
<th class="border-0" style="width: 100%;">{{ __('site.attributes.message') }}</th> <th class="border-0" style="width: 100%;">{{ __('site.attributes.message') }}</th>
<th class="border-0">{{ __('site.attributes.name') }}</th> <th class="border-0">{{ __('site.attributes.name') }}</th>
<th class="border-0">{{ __('site.attributes.email') }}</th> <th class="border-0">{{ __('site.attributes.email') }}</th>
@ -16,6 +17,9 @@
<tbody> <tbody>
@foreach($feedbacks as $feedback) @foreach($feedbacks as $feedback)
<tr> <tr>
<td data-bs-toggle="tooltip" data-bs-placement="top" title="{{ $feedback->created_at->timezone(\App\Helpers\Helpers::getUserTimeZone())->isoFormat('LLL') }}">
{{ $feedback->created_at->diffForHumans() }}
</td>
<td>{!! $feedback->message !!}</td> <td>{!! $feedback->message !!}</td>
<td> <td>
<p>{{ $feedback->name }}</p> <p>{{ $feedback->name }}</p>

View File

@ -3,11 +3,13 @@
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::get('/', [\App\Http\Controllers\Site\ProjectsController::class, 'index'])->name('home'); Route::get('/', [\App\Http\Controllers\Site\ProjectsController::class, 'index'])->name('home');
Route::get('/language/{language}', [\App\Http\Controllers\Site\ProjectsController::class, 'index'])->name('home-language'); Route::middleware([\App\Http\Middleware\IsProject::class, \App\Http\Middleware\IsWebsiteTranslations::class])->group(function () {
Route::get('/language/{language}', [\App\Http\Controllers\Site\ProjectsController::class, 'index'])->name('home-language');
Route::get('feedback', [\App\Http\Controllers\Site\FeedbackController::class, 'index'])->name('feedback'); Route::prefix('feedback')->group(function () {
Route::get('feedback/language/{language}', [\App\Http\Controllers\Site\FeedbackController::class, 'index'])->name('feedback-language'); Route::get('/', [\App\Http\Controllers\Site\FeedbackController::class, 'index'])->name('feedback');
Route::get('feedback/success', [\App\Http\Controllers\Site\FeedbackController::class, 'index'])->name('feedback.success'); Route::get('language/{language}', [\App\Http\Controllers\Site\FeedbackController::class, 'index'])->name('feedback-language');
Route::get('feedback/success/language/{language}', [\App\Http\Controllers\Site\FeedbackController::class, 'index'])->name('feedback.success-language'); Route::post('/', [\App\Http\Controllers\Site\FeedbackController::class, 'send'])->name('feedback.send');
Route::post('feedback', [\App\Http\Controllers\Site\FeedbackController::class, 'send'])->name('feedback.send'); Route::post('language/{language}', [\App\Http\Controllers\Site\FeedbackController::class, 'send'])->name('feedback.send-language');
Route::post('feedback/language/{language}', [\App\Http\Controllers\Site\FeedbackController::class, 'send'])->name('feedback.send-language'); });
});

View File

@ -7,6 +7,12 @@ APP_FORCE_HTTPS=false
CAPTCHA_VERIFICATION_DATA_VIEW_LIMIT_IN_MINUTES=1 CAPTCHA_VERIFICATION_DATA_VIEW_LIMIT_IN_MINUTES=1
APP_CAPTCHA=false
CAPTCHA_API_DOMAIN=http://your-domain-captcha-or-IP:8081
CAPTCHA_PRIVATE_TOKEN=
CAPTCHA_STATIC_PATH=http://your-domain-captcha-or-IP:8081/captcha
CAPTCHA_PUBLIC_TOKEN=
LOGIN_MAX_REQUEST=20 LOGIN_MAX_REQUEST=20
LOGIN_MAX_EMAIL_REQUEST=10 LOGIN_MAX_EMAIL_REQUEST=10
@ -70,3 +76,21 @@ VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}" VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
REVERB_APP_ID=
REVERB_APP_KEY=
REVERB_APP_SECRET=
REVERB_HOST="captcha-reverb"
REVERB_PORT=9000
REVERB_SCHEME=http
# * or localhost.com or localhost.com, localhost.net
REVERB_ALLOWED_ORIGINS="*"
REVERB_HOST_CLIENT="localhost"
REVERB_PORT_CLIENT=8081
REVERB_SCHEME_CLIENT=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

View File

@ -19,7 +19,7 @@ services:
# restart: always # restart: always
captcha-app: captcha-app:
image: korelf/service-captcha:0.7.1 image: korelf/service-captcha:0.8.1
# restart: always # restart: always
cap_drop: cap_drop:
- ALL - ALL
@ -34,6 +34,35 @@ services:
env_file: captcha-app/.env env_file: captcha-app/.env
ports: ports:
- ${DOCKER_CAPTCHA_PORT}:9000 - ${DOCKER_CAPTCHA_PORT}:9000
captcha-queue:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: queue
env_file: captcha-app/.env
captcha-reverb:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: websockets
env_file: captcha-app/.env
ports:
- ${DOCKER_CAPTCHA_WEBSOCKET_PORT}:9000
captcha-scheduler:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: scheduler
env_file: captcha-app/.env
captcha-redis: captcha-redis:
image: redis:3.0-alpine image: redis:3.0-alpine
# restart: always # restart: always

View File

@ -18,7 +18,7 @@ services:
# restart: always # restart: always
captcha-app: captcha-app:
image: korelf/service-captcha:0.7.1 image: korelf/service-captcha:0.8.1
# restart: always # restart: always
cap_drop: cap_drop:
- ALL - ALL
@ -33,6 +33,35 @@ services:
env_file: captcha-app/.env env_file: captcha-app/.env
ports: ports:
- ${DOCKER_CAPTCHA_PORT}:9000 - ${DOCKER_CAPTCHA_PORT}:9000
captcha-queue:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: queue
env_file: captcha-app/.env
captcha-reverb:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: websockets
env_file: captcha-app/.env
ports:
- ${DOCKER_CAPTCHA_WEBSOCKET_PORT}:9000
captcha-scheduler:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: scheduler
env_file: captcha-app/.env
captcha-redis: captcha-redis:
image: redis:3.0-alpine image: redis:3.0-alpine
# restart: always # restart: always

View File

@ -17,7 +17,7 @@ services:
image: redis:3.0-alpine image: redis:3.0-alpine
captcha-app: captcha-app:
image: korelf/service-captcha:0.7.0 image: korelf/service-captcha:0.8.1
cap_drop: cap_drop:
- ALL - ALL
cap_add: cap_add:
@ -31,6 +31,35 @@ services:
env_file: captcha-app/.env env_file: captcha-app/.env
ports: ports:
- ${DOCKER_CAPTCHA_PORT}:9000 - ${DOCKER_CAPTCHA_PORT}:9000
captcha-queue:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: queue
env_file: captcha-app/.env
captcha-reverb:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: websockets
env_file: captcha-app/.env
ports:
- ${DOCKER_CAPTCHA_WEBSOCKET_PORT}:9000
captcha-scheduler:
image: korelf/service-captcha:0.8.1
# restart: always
depends_on:
- db
- captcha-redis
environment:
CONTAINER_ROLE: scheduler
env_file: captcha-app/.env
captcha-redis: captcha-redis:
image: redis:3.0-alpine image: redis:3.0-alpine
db: db: