feat: add user-set icon prefix functionality and update icon rendering in Proxmox services
This commit is contained in:
@@ -13,6 +13,7 @@ class ServerIconController
|
||||
$request->validate([
|
||||
'icon' => 'nullable|string|max:64',
|
||||
'color' => 'nullable|string|max:32',
|
||||
'prefix' => 'nullable|string|max:32',
|
||||
]);
|
||||
|
||||
$server = Server::where('id', $serverId)
|
||||
@@ -21,6 +22,7 @@ class ServerIconController
|
||||
|
||||
$server->user_set_icon = $request->input('icon');
|
||||
$server->user_set_icon_color = $request->input('color');
|
||||
$server->user_set_icon_prefix = $request->input('prefix', 'ri');
|
||||
$server->save();
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
@@ -34,6 +36,7 @@ class ServerIconController
|
||||
return response()->json([
|
||||
'icon' => $server->user_set_icon,
|
||||
'color' => $server->user_set_icon_color,
|
||||
'prefix' => $server->user_set_icon_prefix ?? 'ri',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('ext_proxmox_servers', function (Blueprint $table) {
|
||||
$table->string('user_set_icon_prefix', 32)->nullable()->after('user_set_icon_color');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('ext_proxmox_servers', function (Blueprint $table) {
|
||||
$table->dropColumn('user_set_icon_prefix');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -41,10 +41,11 @@
|
||||
<div class="flex items-center gap-3" x-data="serverIconModal({
|
||||
serverId: '{{ $server->id }}',
|
||||
initialIcon: {{ $server->user_set_icon ? "'" . $server->user_set_icon . "'" : 'null' }},
|
||||
initialColor: {{ $server->user_set_icon_color ? "'" . $server->user_set_icon_color . "'" : 'null' }}
|
||||
initialColor: {{ $server->user_set_icon_color ? "'" . $server->user_set_icon_color . "'" : 'null' }},
|
||||
initialPrefix: {{ $server->user_set_icon_prefix ? "'" . $server->user_set_icon_prefix . "'" : "'ri'" }}
|
||||
})">
|
||||
<button @click="openModal()" :title="icon ? 'Customize server icon' : 'Set server icon'" class="flex items-center gap-3 hover:opacity-80 transition-opacity">
|
||||
<div x-show="icon" :style="color ? 'color: ' + color : ''" x-html="getIconSvg(icon)" class="size-6"></div>
|
||||
<div x-show="icon" :style="color ? 'color: ' + color : ''" x-html="getIconSvg(icon, iconPrefix)" class="size-6"></div>
|
||||
<x-ri-server-line x-show="!icon" class="size-6 text-secondary" />
|
||||
<span class="text-2xl font-bold">
|
||||
{{ $server->hostname }}
|
||||
@@ -60,7 +61,7 @@
|
||||
<h3 class="text-lg font-semibold mb-4">Customize Server Icon</h3>
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="size-12 rounded-xl border flex items-center justify-center" :style="color ? 'border-color: ' + color : ''">
|
||||
<div x-show="icon" :style="color ? 'color: ' + color : ''" x-html="getIconSvg(icon)"></div>
|
||||
<div x-show="icon" :style="color ? 'color: ' + color : ''" x-html="getIconSvg(icon, iconPrefix)"></div>
|
||||
<x-ri-server-line x-show="!icon" class="size-8 text-base/40" />
|
||||
</div>
|
||||
<input x-model="search" x-on:input="filterIcons()" type="text" placeholder="Search icons..." class="border rounded px-2 py-1 text-sm w-40 dark:bg-background dark:border-base/20" />
|
||||
@@ -68,32 +69,202 @@
|
||||
<div class="grid grid-cols-6 gap-2 mb-4 max-h-32 overflow-y-auto p-1">
|
||||
@php
|
||||
$iconList = [
|
||||
'server-line', 'database-2-line', 'computer-line', 'cpu-line', 'hard-drive-2-line',
|
||||
'cloud-line', 'terminal-box-line', 'code-s-slash-line', 'braces-line',
|
||||
'global-line', 'earth-line', 'wifi-line', 'signal-tower-line',
|
||||
'shield-check-line', 'shield-keyhole-line', 'lock-line', 'lock-unlock-line', 'key-2-line',
|
||||
'rocket-line', 'rocket-2-line', 'send-plane-line', 'flashlight-line', 'fire-line',
|
||||
'sparkling-line', 'star-line', 'heart-line', 'home-line', 'home-2-line',
|
||||
'building-line', 'building-2-line', 'store-line', 'box-3-line', 'archive-line',
|
||||
'inbox-line', 'inbox-2-line', 'folder-line', 'folder-open-line',
|
||||
'settings-3-line', 'settings-4-line', 'tools-line', 'hammer-line',
|
||||
'flask-line', 'bug-line', 'puzzle-line', 'bar-chart-box-line', 'pie-chart-line',
|
||||
'line-chart-line', 'money-dollar-circle-line', 'money-euro-circle-line',
|
||||
'bank-card-line', 'wallet-line', 'user-line', 'user-3-line', 'group-line', 'team-line',
|
||||
'mail-line', 'mail-open-line', 'chat-3-line', 'discuss-line',
|
||||
'camera-line', 'vidicon-line', 'film-line', 'music-line',
|
||||
'book-open-line', 'file-text-line', 'sun-line', 'moon-line',
|
||||
'palette-line', 'brush-line', 'trophy-line', 'graduation-cap-line',
|
||||
'lightbulb-line', 'fingerprint-line', 'eye-line', 'map-2-line', 'map-pin-line',
|
||||
'time-line', 'calendar-line', 'gift-line', 'cake-2-line',
|
||||
'gamepad-line', 'ghost-line', 'aliens-line', 'space-ship-line',
|
||||
'android-line', 'apple-line', 'windows-line', 'ubuntu-line',
|
||||
'github-line', 'gitlab-line', 'discord-line', 'slack-line'
|
||||
// Remix Icons
|
||||
['icon' => 'server-line', 'prefix' => 'ri'],
|
||||
['icon' => 'database-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'computer-line', 'prefix' => 'ri'],
|
||||
['icon' => 'cpu-line', 'prefix' => 'ri'],
|
||||
['icon' => 'hard-drive-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'cloud-line', 'prefix' => 'ri'],
|
||||
['icon' => 'terminal-box-line', 'prefix' => 'ri'],
|
||||
['icon' => 'code-s-slash-line', 'prefix' => 'ri'],
|
||||
['icon' => 'braces-line', 'prefix' => 'ri'],
|
||||
['icon' => 'global-line', 'prefix' => 'ri'],
|
||||
['icon' => 'earth-line', 'prefix' => 'ri'],
|
||||
['icon' => 'wifi-line', 'prefix' => 'ri'],
|
||||
['icon' => 'signal-tower-line', 'prefix' => 'ri'],
|
||||
['icon' => 'shield-check-line', 'prefix' => 'ri'],
|
||||
['icon' => 'shield-keyhole-line', 'prefix' => 'ri'],
|
||||
['icon' => 'lock-line', 'prefix' => 'ri'],
|
||||
['icon' => 'lock-unlock-line', 'prefix' => 'ri'],
|
||||
['icon' => 'key-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'rocket-line', 'prefix' => 'ri'],
|
||||
['icon' => 'rocket-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'send-plane-line', 'prefix' => 'ri'],
|
||||
['icon' => 'flashlight-line', 'prefix' => 'ri'],
|
||||
['icon' => 'fire-line', 'prefix' => 'ri'],
|
||||
['icon' => 'sparkling-line', 'prefix' => 'ri'],
|
||||
['icon' => 'star-line', 'prefix' => 'ri'],
|
||||
['icon' => 'heart-line', 'prefix' => 'ri'],
|
||||
['icon' => 'home-line', 'prefix' => 'ri'],
|
||||
['icon' => 'home-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'building-line', 'prefix' => 'ri'],
|
||||
['icon' => 'building-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'store-line', 'prefix' => 'ri'],
|
||||
['icon' => 'box-3-line', 'prefix' => 'ri'],
|
||||
['icon' => 'archive-line', 'prefix' => 'ri'],
|
||||
['icon' => 'inbox-line', 'prefix' => 'ri'],
|
||||
['icon' => 'inbox-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'folder-line', 'prefix' => 'ri'],
|
||||
['icon' => 'folder-open-line', 'prefix' => 'ri'],
|
||||
['icon' => 'settings-3-line', 'prefix' => 'ri'],
|
||||
['icon' => 'settings-4-line', 'prefix' => 'ri'],
|
||||
['icon' => 'tools-line', 'prefix' => 'ri'],
|
||||
['icon' => 'hammer-line', 'prefix' => 'ri'],
|
||||
['icon' => 'flask-line', 'prefix' => 'ri'],
|
||||
['icon' => 'bug-line', 'prefix' => 'ri'],
|
||||
['icon' => 'puzzle-line', 'prefix' => 'ri'],
|
||||
['icon' => 'bar-chart-box-line', 'prefix' => 'ri'],
|
||||
['icon' => 'pie-chart-line', 'prefix' => 'ri'],
|
||||
['icon' => 'line-chart-line', 'prefix' => 'ri'],
|
||||
['icon' => 'money-dollar-circle-line', 'prefix' => 'ri'],
|
||||
['icon' => 'money-euro-circle-line', 'prefix' => 'ri'],
|
||||
['icon' => 'bank-card-line', 'prefix' => 'ri'],
|
||||
['icon' => 'wallet-line', 'prefix' => 'ri'],
|
||||
['icon' => 'user-line', 'prefix' => 'ri'],
|
||||
['icon' => 'user-3-line', 'prefix' => 'ri'],
|
||||
['icon' => 'group-line', 'prefix' => 'ri'],
|
||||
['icon' => 'team-line', 'prefix' => 'ri'],
|
||||
['icon' => 'mail-line', 'prefix' => 'ri'],
|
||||
['icon' => 'mail-open-line', 'prefix' => 'ri'],
|
||||
['icon' => 'chat-3-line', 'prefix' => 'ri'],
|
||||
['icon' => 'discuss-line', 'prefix' => 'ri'],
|
||||
['icon' => 'camera-line', 'prefix' => 'ri'],
|
||||
['icon' => 'vidicon-line', 'prefix' => 'ri'],
|
||||
['icon' => 'film-line', 'prefix' => 'ri'],
|
||||
['icon' => 'music-line', 'prefix' => 'ri'],
|
||||
['icon' => 'book-open-line', 'prefix' => 'ri'],
|
||||
['icon' => 'file-text-line', 'prefix' => 'ri'],
|
||||
['icon' => 'sun-line', 'prefix' => 'ri'],
|
||||
['icon' => 'moon-line', 'prefix' => 'ri'],
|
||||
['icon' => 'palette-line', 'prefix' => 'ri'],
|
||||
['icon' => 'brush-line', 'prefix' => 'ri'],
|
||||
['icon' => 'trophy-line', 'prefix' => 'ri'],
|
||||
['icon' => 'graduation-cap-line', 'prefix' => 'ri'],
|
||||
['icon' => 'lightbulb-line', 'prefix' => 'ri'],
|
||||
['icon' => 'fingerprint-line', 'prefix' => 'ri'],
|
||||
['icon' => 'eye-line', 'prefix' => 'ri'],
|
||||
['icon' => 'map-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'map-pin-line', 'prefix' => 'ri'],
|
||||
['icon' => 'time-line', 'prefix' => 'ri'],
|
||||
['icon' => 'calendar-line', 'prefix' => 'ri'],
|
||||
['icon' => 'gift-line', 'prefix' => 'ri'],
|
||||
['icon' => 'cake-2-line', 'prefix' => 'ri'],
|
||||
['icon' => 'gamepad-line', 'prefix' => 'ri'],
|
||||
['icon' => 'ghost-line', 'prefix' => 'ri'],
|
||||
['icon' => 'aliens-line', 'prefix' => 'ri'],
|
||||
['icon' => 'space-ship-line', 'prefix' => 'ri'],
|
||||
['icon' => 'android-line', 'prefix' => 'ri'],
|
||||
['icon' => 'apple-line', 'prefix' => 'ri'],
|
||||
['icon' => 'windows-line', 'prefix' => 'ri'],
|
||||
['icon' => 'ubuntu-line', 'prefix' => 'ri'],
|
||||
['icon' => 'github-line', 'prefix' => 'ri'],
|
||||
['icon' => 'gitlab-line', 'prefix' => 'ri'],
|
||||
['icon' => 'discord-line', 'prefix' => 'ri'],
|
||||
['icon' => 'slack-line', 'prefix' => 'ri'],
|
||||
// Vaadin Icons
|
||||
['icon' => 'server', 'prefix' => 'vaadin'],
|
||||
['icon' => 'database', 'prefix' => 'vaadin'],
|
||||
['icon' => 'desktop', 'prefix' => 'vaadin'],
|
||||
['icon' => 'laptop', 'prefix' => 'vaadin'],
|
||||
['icon' => 'cluster', 'prefix' => 'vaadin'],
|
||||
['icon' => 'cloud', 'prefix' => 'vaadin'],
|
||||
['icon' => 'cloud-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'cloud-upload', 'prefix' => 'vaadin'],
|
||||
['icon' => 'cloud-download', 'prefix' => 'vaadin'],
|
||||
['icon' => 'storage', 'prefix' => 'vaadin'],
|
||||
['icon' => 'harddrive', 'prefix' => 'vaadin'],
|
||||
['icon' => 'compile', 'prefix' => 'vaadin'],
|
||||
['icon' => 'code', 'prefix' => 'vaadin'],
|
||||
['icon' => 'terminal', 'prefix' => 'vaadin'],
|
||||
['icon' => 'globe', 'prefix' => 'vaadin'],
|
||||
['icon' => 'globe-wire', 'prefix' => 'vaadin'],
|
||||
['icon' => 'connect', 'prefix' => 'vaadin'],
|
||||
['icon' => 'sitemap', 'prefix' => 'vaadin'],
|
||||
['icon' => 'automation', 'prefix' => 'vaadin'],
|
||||
['icon' => 'cogs', 'prefix' => 'vaadin'],
|
||||
['icon' => 'cog', 'prefix' => 'vaadin'],
|
||||
['icon' => 'wrench', 'prefix' => 'vaadin'],
|
||||
['icon' => 'tools', 'prefix' => 'vaadin'],
|
||||
['icon' => 'hammer', 'prefix' => 'vaadin'],
|
||||
['icon' => 'shield', 'prefix' => 'vaadin'],
|
||||
['icon' => 'lock', 'prefix' => 'vaadin'],
|
||||
['icon' => 'unlock', 'prefix' => 'vaadin'],
|
||||
['icon' => 'key', 'prefix' => 'vaadin'],
|
||||
['icon' => 'key-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'rocket', 'prefix' => 'vaadin'],
|
||||
['icon' => 'flash', 'prefix' => 'vaadin'],
|
||||
['icon' => 'bolt', 'prefix' => 'vaadin'],
|
||||
['icon' => 'fire', 'prefix' => 'vaadin'],
|
||||
['icon' => 'star', 'prefix' => 'vaadin'],
|
||||
['icon' => 'star-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'heart', 'prefix' => 'vaadin'],
|
||||
['icon' => 'heart-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'home', 'prefix' => 'vaadin'],
|
||||
['icon' => 'home-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'building', 'prefix' => 'vaadin'],
|
||||
['icon' => 'building-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'office', 'prefix' => 'vaadin'],
|
||||
['icon' => 'package', 'prefix' => 'vaadin'],
|
||||
['icon' => 'archive', 'prefix' => 'vaadin'],
|
||||
['icon' => 'inbox', 'prefix' => 'vaadin'],
|
||||
['icon' => 'folder', 'prefix' => 'vaadin'],
|
||||
['icon' => 'folder-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'folder-open', 'prefix' => 'vaadin'],
|
||||
['icon' => 'folder-open-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'bug', 'prefix' => 'vaadin'],
|
||||
['icon' => 'chart', 'prefix' => 'vaadin'],
|
||||
['icon' => 'bar-chart', 'prefix' => 'vaadin'],
|
||||
['icon' => 'line-chart', 'prefix' => 'vaadin'],
|
||||
['icon' => 'pie-chart', 'prefix' => 'vaadin'],
|
||||
['icon' => 'dashboard', 'prefix' => 'vaadin'],
|
||||
['icon' => 'progressbar', 'prefix' => 'vaadin'],
|
||||
['icon' => 'money', 'prefix' => 'vaadin'],
|
||||
['icon' => 'dollar', 'prefix' => 'vaadin'],
|
||||
['icon' => 'euro', 'prefix' => 'vaadin'],
|
||||
['icon' => 'credit-card', 'prefix' => 'vaadin'],
|
||||
['icon' => 'wallet', 'prefix' => 'vaadin'],
|
||||
['icon' => 'user', 'prefix' => 'vaadin'],
|
||||
['icon' => 'users', 'prefix' => 'vaadin'],
|
||||
['icon' => 'group', 'prefix' => 'vaadin'],
|
||||
['icon' => 'user-card', 'prefix' => 'vaadin'],
|
||||
['icon' => 'male', 'prefix' => 'vaadin'],
|
||||
['icon' => 'female', 'prefix' => 'vaadin'],
|
||||
['icon' => 'envelope', 'prefix' => 'vaadin'],
|
||||
['icon' => 'envelope-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'envelope-open', 'prefix' => 'vaadin'],
|
||||
['icon' => 'mailbox', 'prefix' => 'vaadin'],
|
||||
['icon' => 'comment', 'prefix' => 'vaadin'],
|
||||
['icon' => 'comments', 'prefix' => 'vaadin'],
|
||||
['icon' => 'comments-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'camera', 'prefix' => 'vaadin'],
|
||||
['icon' => 'film', 'prefix' => 'vaadin'],
|
||||
['icon' => 'music', 'prefix' => 'vaadin'],
|
||||
['icon' => 'book', 'prefix' => 'vaadin'],
|
||||
['icon' => 'file-text', 'prefix' => 'vaadin'],
|
||||
['icon' => 'file-text-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'sun-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'moon-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'palette', 'prefix' => 'vaadin'],
|
||||
['icon' => 'paintbrush', 'prefix' => 'vaadin'],
|
||||
['icon' => 'trophy', 'prefix' => 'vaadin'],
|
||||
['icon' => 'academy-cap', 'prefix' => 'vaadin'],
|
||||
['icon' => 'lightbulb', 'prefix' => 'vaadin'],
|
||||
['icon' => 'eye', 'prefix' => 'vaadin'],
|
||||
['icon' => 'eye-slash', 'prefix' => 'vaadin'],
|
||||
['icon' => 'map-marker', 'prefix' => 'vaadin'],
|
||||
['icon' => 'location-arrow', 'prefix' => 'vaadin'],
|
||||
['icon' => 'clock', 'prefix' => 'vaadin'],
|
||||
['icon' => 'calendar', 'prefix' => 'vaadin'],
|
||||
['icon' => 'calendar-o', 'prefix' => 'vaadin'],
|
||||
['icon' => 'gift', 'prefix' => 'vaadin'],
|
||||
['icon' => 'gamepad', 'prefix' => 'vaadin'],
|
||||
['icon' => 'controller', 'prefix' => 'vaadin'],
|
||||
];
|
||||
@endphp
|
||||
@foreach($iconList as $iconName)
|
||||
<button @click="icon = '{{ $iconName }}'" :class="icon === '{{ $iconName }}' ? 'ring-2 ring-primary' : ''" class="icon-btn rounded p-2 border flex items-center justify-center hover:bg-secondary/10 dark:border-base/20" data-icon="{{ $iconName }}">
|
||||
<x-dynamic-component :component="'ri-' . $iconName" class="size-5" />
|
||||
@foreach($iconList as $iconData)
|
||||
<button @click="icon = '{{ $iconData['icon'] }}'; iconPrefix = '{{ $iconData['prefix'] }}'" :class="icon === '{{ $iconData['icon'] }}' && iconPrefix === '{{ $iconData['prefix'] }}' ? 'ring-2 ring-primary' : ''" class="icon-btn rounded p-2 border flex items-center justify-center hover:bg-secondary/10 dark:border-base/20" data-icon="{{ $iconData['icon'] }}" data-prefix="{{ $iconData['prefix'] }}">
|
||||
<x-dynamic-component :component="$iconData['prefix'] . '-' . $iconData['icon']" class="size-5" />
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
@@ -113,10 +284,11 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function serverIconModal({serverId, initialIcon, initialColor}) {
|
||||
function serverIconModal({serverId, initialIcon, initialColor, initialPrefix}) {
|
||||
return {
|
||||
show: false,
|
||||
icon: initialIcon || '',
|
||||
iconPrefix: initialPrefix || 'ri',
|
||||
color: initialColor || '',
|
||||
search: '',
|
||||
message: '',
|
||||
@@ -133,17 +305,20 @@
|
||||
closeModal() { this.show = false; },
|
||||
resetIcon() {
|
||||
this.icon = '';
|
||||
this.iconPrefix = 'ri';
|
||||
this.color = '';
|
||||
},
|
||||
filterIcons() {
|
||||
const query = this.search.toLowerCase();
|
||||
document.querySelectorAll('.icon-btn').forEach(btn => {
|
||||
const iconName = btn.dataset.icon;
|
||||
btn.style.display = !query || iconName.includes(query) ? 'flex' : 'none';
|
||||
const iconPrefix = btn.dataset.prefix;
|
||||
const searchText = iconPrefix + '-' + iconName;
|
||||
btn.style.display = !query || searchText.includes(query) ? 'flex' : 'none';
|
||||
});
|
||||
},
|
||||
getIconSvg(iconName) {
|
||||
const btn = document.querySelector(`.icon-btn[data-icon="${iconName}"]`);
|
||||
getIconSvg(iconName, prefix) {
|
||||
const btn = document.querySelector(`.icon-btn[data-icon="${iconName}"][data-prefix="${prefix}"]`);
|
||||
if (btn) {
|
||||
const svg = btn.querySelector('svg');
|
||||
if (svg) {
|
||||
@@ -162,7 +337,7 @@
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content
|
||||
},
|
||||
body: JSON.stringify({ icon: this.icon, color: this.color })
|
||||
body: JSON.stringify({ icon: this.icon, color: this.color, prefix: this.iconPrefix })
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
|
||||
Reference in New Issue
Block a user