Update guest PWA v2 UI and likes
This commit is contained in:
@@ -28,6 +28,7 @@ use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Arr;
|
||||
use UnitEnum;
|
||||
|
||||
class EventResource extends Resource
|
||||
@@ -264,6 +265,67 @@ class EventResource extends Resource
|
||||
->success()
|
||||
->send();
|
||||
}),
|
||||
Actions\Action::make('set_demo_read_only')
|
||||
->label(__('admin.events.join_link.demo_read_only_action'))
|
||||
->icon('heroicon-o-lock-closed')
|
||||
->color('gray')
|
||||
->size('xs')
|
||||
->modalHeading(function (Actions\Action $action, Event $record): string {
|
||||
$token = static::resolveJoinTokenFromAction($record, $action);
|
||||
|
||||
return $token
|
||||
? __('admin.events.join_link.demo_read_only_heading', [
|
||||
'label' => $token->label ?: __('admin.events.join_link.token_default', ['id' => $token->id]),
|
||||
])
|
||||
: __('admin.events.join_link.demo_read_only_heading_fallback');
|
||||
})
|
||||
->schema([
|
||||
Toggle::make('demo_read_only')
|
||||
->label(__('admin.events.join_link.demo_read_only_label'))
|
||||
->helperText(__('admin.events.join_link.demo_read_only_help')),
|
||||
])
|
||||
->fillForm(function (Actions\Action $action, Event $record): array {
|
||||
$token = static::resolveJoinTokenFromAction($record, $action);
|
||||
|
||||
return [
|
||||
'demo_read_only' => (bool) Arr::get($token?->metadata ?? [], 'demo_read_only', false),
|
||||
];
|
||||
})
|
||||
->action(function (array $data, Actions\Action $action, Event $record): void {
|
||||
$token = static::resolveJoinTokenFromAction($record, $action);
|
||||
|
||||
if (! $token) {
|
||||
Notification::make()
|
||||
->title(__('admin.events.join_link.demo_read_only_missing'))
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$metadata = is_array($token->metadata) ? $token->metadata : [];
|
||||
$enabled = (bool) ($data['demo_read_only'] ?? false);
|
||||
|
||||
if ($enabled) {
|
||||
$metadata['demo_read_only'] = true;
|
||||
} else {
|
||||
unset($metadata['demo_read_only']);
|
||||
}
|
||||
|
||||
$token->metadata = empty($metadata) ? null : $metadata;
|
||||
$token->save();
|
||||
|
||||
app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$token,
|
||||
source: static::class
|
||||
);
|
||||
|
||||
Notification::make()
|
||||
->title(__('admin.events.join_link.demo_read_only_success'))
|
||||
->success()
|
||||
->send();
|
||||
}),
|
||||
])
|
||||
->modalContent(function (Actions\Action $action, $record) {
|
||||
$tokens = $record->joinTokens()
|
||||
@@ -335,6 +397,7 @@ class EventResource extends Resource
|
||||
'expires_at' => optional($token->expires_at)->toIso8601String(),
|
||||
'revoked_at' => optional($token->revoked_at)->toIso8601String(),
|
||||
'is_active' => $token->isActive(),
|
||||
'demo_read_only' => (bool) Arr::get($token->metadata ?? [], 'demo_read_only', false),
|
||||
'created_at' => optional($token->created_at)->toIso8601String(),
|
||||
'layouts' => $layouts,
|
||||
'layouts_url' => route('api.v1.tenant.events.join-tokens.layouts.index', [
|
||||
|
||||
@@ -2985,6 +2985,54 @@ class EventPublicController extends BaseController
|
||||
return response()->json(['liked' => true, 'likes_count' => $count]);
|
||||
}
|
||||
|
||||
public function unlike(Request $request, int $id)
|
||||
{
|
||||
$deviceId = (string) $request->header('X-Device-Id', 'anon');
|
||||
$deviceId = substr(preg_replace('/[^a-zA-Z0-9_-]/', '', $deviceId), 0, 64);
|
||||
if ($deviceId === '') {
|
||||
$deviceId = 'anon';
|
||||
}
|
||||
|
||||
$photo = DB::table('photos')
|
||||
->join('events', 'photos.event_id', '=', 'events.id')
|
||||
->where('photos.id', $id)
|
||||
->where('events.status', 'published')
|
||||
->first(['photos.id', 'photos.event_id']);
|
||||
if (! $photo) {
|
||||
return ApiError::response(
|
||||
'photo_not_found',
|
||||
'Photo Not Found',
|
||||
'Photo not found or event not public.',
|
||||
Response::HTTP_NOT_FOUND,
|
||||
['photo_id' => $id]
|
||||
);
|
||||
}
|
||||
|
||||
$exists = DB::table('photo_likes')->where('photo_id', $id)->where('guest_name', $deviceId)->exists();
|
||||
if (! $exists) {
|
||||
$count = (int) DB::table('photos')->where('id', $id)->value('likes_count');
|
||||
|
||||
return response()->json(['liked' => false, 'likes_count' => $count]);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
DB::table('photo_likes')->where('photo_id', $id)->where('guest_name', $deviceId)->delete();
|
||||
DB::table('photos')->where('id', $id)->update([
|
||||
'likes_count' => DB::raw('case when likes_count > 0 then likes_count - 1 else 0 end'),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
DB::commit();
|
||||
} catch (\Throwable $e) {
|
||||
DB::rollBack();
|
||||
Log::warning('unlike failed', ['error' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
$count = (int) DB::table('photos')->where('id', $id)->value('likes_count');
|
||||
|
||||
return response()->json(['liked' => false, 'likes_count' => $count]);
|
||||
}
|
||||
|
||||
public function upload(Request $request, string $token)
|
||||
{
|
||||
$result = $this->resolvePublishedEvent($request, $token, ['id']);
|
||||
|
||||
@@ -81,6 +81,11 @@ class ContentSecurityPolicy
|
||||
'https:',
|
||||
];
|
||||
|
||||
$workerSources = [
|
||||
"'self'",
|
||||
'blob:',
|
||||
];
|
||||
|
||||
$paypalSources = [
|
||||
'https://www.paypal.com',
|
||||
'https://www.paypalobjects.com',
|
||||
@@ -153,6 +158,7 @@ class ContentSecurityPolicy
|
||||
'font-src' => array_unique($fontSources),
|
||||
'connect-src' => array_unique($connectSources),
|
||||
'media-src' => array_unique($mediaSources),
|
||||
'worker-src' => array_unique($workerSources),
|
||||
'frame-src' => array_unique($frameSources),
|
||||
'form-action' => ["'self'"],
|
||||
'base-uri' => ["'self'"],
|
||||
|
||||
Reference in New Issue
Block a user