Merge branch 'next' into fix-postgres-init-scripts
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
<div
|
||||
class="w-full bg-white shadow md:mt-0 sm:max-w-md xl:p-0 dark:bg-base ">
|
||||
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
|
||||
@if (is_transactional_emails_active())
|
||||
@if (is_transactional_emails_enabled())
|
||||
<form action="/forgot-password" method="POST" class="flex flex-col gap-2">
|
||||
@csrf
|
||||
<x-forms.input required type="email" name="email" label="{{ __('input.email') }}" />
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
|
||||
<div class="p-6 space-y-4 md:space-y-3 sm:p-8">
|
||||
<form action="/login" method="POST" class="flex flex-col gap-2">
|
||||
@csrf
|
||||
@env('local')
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
monacoLoader: true,
|
||||
monacoFontSize: '15px',
|
||||
monacoId: $id('monaco-editor'),
|
||||
isDarkMode() {
|
||||
return document.documentElement.classList.contains('dark') || localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||
},
|
||||
monacoEditor(editor) {
|
||||
editor.onDidChangeModelContent((e) => {
|
||||
this.monacoContent = editor.getValue();
|
||||
@@ -41,357 +44,9 @@
|
||||
let proxy = URL.createObjectURL(new Blob([` self.MonacoEnvironment = { baseUrl: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.39.0/min' }; importScripts('https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.39.0/min/vs/base/worker/workerMain.min.js');`], { type: 'text/javascript' }));
|
||||
window.MonacoEnvironment = { getWorkerUrl: () => proxy };
|
||||
require(['vs/editor/editor.main'], () => {
|
||||
monaco.editor.defineTheme('blackboard', {
|
||||
'base': 'vs-dark',
|
||||
'inherit': true,
|
||||
'rules': [{
|
||||
'background': editorBackground,
|
||||
'token': ''
|
||||
},
|
||||
{
|
||||
'foreground': '959da5',
|
||||
'token': 'comment'
|
||||
},
|
||||
{
|
||||
'foreground': '959da5',
|
||||
'token': 'punctuation.definition.comment'
|
||||
},
|
||||
{
|
||||
'foreground': '959da5',
|
||||
'token': 'string.comment'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'constant'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'entity.name.constant'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'variable.other.constant'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'variable.language'
|
||||
},
|
||||
{
|
||||
'foreground': 'b392f0',
|
||||
'token': 'entity'
|
||||
},
|
||||
{
|
||||
'foreground': 'b392f0',
|
||||
'token': 'entity.name'
|
||||
},
|
||||
{
|
||||
'foreground': 'f6f8fa',
|
||||
'token': 'variable.parameter.function'
|
||||
},
|
||||
{
|
||||
'foreground': '7bcc72',
|
||||
'token': 'entity.name.tag'
|
||||
},
|
||||
{
|
||||
'foreground': 'ea4a5a',
|
||||
'token': 'keyword'
|
||||
},
|
||||
{
|
||||
'foreground': 'ea4a5a',
|
||||
'token': 'storage'
|
||||
},
|
||||
{
|
||||
'foreground': 'ea4a5a',
|
||||
'token': 'storage.type'
|
||||
},
|
||||
{
|
||||
'foreground': 'f6f8fa',
|
||||
'token': 'storage.modifier.package'
|
||||
},
|
||||
{
|
||||
'foreground': 'f6f8fa',
|
||||
'token': 'storage.modifier.import'
|
||||
},
|
||||
{
|
||||
'foreground': 'f6f8fa',
|
||||
'token': 'storage.type.java'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'string'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'punctuation.definition.string'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'string punctuation.section.embedded source'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'support'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'meta.property-name'
|
||||
},
|
||||
{
|
||||
'foreground': 'fb8532',
|
||||
'token': 'variable'
|
||||
},
|
||||
{
|
||||
'foreground': 'f6f8fa',
|
||||
'token': 'variable.other'
|
||||
},
|
||||
{
|
||||
'foreground': 'd73a49',
|
||||
'fontStyle': 'bold italic underline',
|
||||
'token': 'invalid.broken'
|
||||
},
|
||||
{
|
||||
'foreground': 'd73a49',
|
||||
'fontStyle': 'bold italic underline',
|
||||
'token': 'invalid.deprecated'
|
||||
},
|
||||
{
|
||||
'foreground': 'fafbfc',
|
||||
'background': 'd73a49',
|
||||
'fontStyle': 'italic underline',
|
||||
'token': 'invalid.illegal'
|
||||
},
|
||||
{
|
||||
'foreground': 'fafbfc',
|
||||
'background': 'd73a49',
|
||||
'fontStyle': 'italic underline',
|
||||
'token': 'carriage-return'
|
||||
},
|
||||
{
|
||||
'foreground': 'd73a49',
|
||||
'fontStyle': 'bold italic underline',
|
||||
'token': 'invalid.unimplemented'
|
||||
},
|
||||
{
|
||||
'foreground': 'd73a49',
|
||||
'token': 'message.error'
|
||||
},
|
||||
{
|
||||
'foreground': 'f6f8fa',
|
||||
'token': 'string source'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'string variable'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'source.regexp'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'string.regexp'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'string.regexp.character-class'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'string.regexp constant.character.escape'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'string.regexp source.ruby.embedded'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'token': 'string.regexp string.regexp.arbitrary-repitition'
|
||||
},
|
||||
{
|
||||
'foreground': '7bcc72',
|
||||
'fontStyle': 'bold',
|
||||
'token': 'string.regexp constant.character.escape'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'support.constant'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'support.variable'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'meta.module-reference'
|
||||
},
|
||||
{
|
||||
'foreground': 'fb8532',
|
||||
'token': 'markup.list'
|
||||
},
|
||||
{
|
||||
'foreground': '0366d6',
|
||||
'fontStyle': 'bold',
|
||||
'token': 'markup.heading'
|
||||
},
|
||||
{
|
||||
'foreground': '0366d6',
|
||||
'fontStyle': 'bold',
|
||||
'token': 'markup.heading entity.name'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'markup.quote'
|
||||
},
|
||||
{
|
||||
'foreground': 'f6f8fa',
|
||||
'fontStyle': 'italic',
|
||||
'token': 'markup.italic'
|
||||
},
|
||||
{
|
||||
'foreground': 'f6f8fa',
|
||||
'fontStyle': 'bold',
|
||||
'token': 'markup.bold'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'markup.raw'
|
||||
},
|
||||
{
|
||||
'foreground': 'b31d28',
|
||||
'background': 'ffeef0',
|
||||
'token': 'markup.deleted'
|
||||
},
|
||||
{
|
||||
'foreground': 'b31d28',
|
||||
'background': 'ffeef0',
|
||||
'token': 'meta.diff.header.from-file'
|
||||
},
|
||||
{
|
||||
'foreground': 'b31d28',
|
||||
'background': 'ffeef0',
|
||||
'token': 'punctuation.definition.deleted'
|
||||
},
|
||||
{
|
||||
'foreground': '176f2c',
|
||||
'background': 'f0fff4',
|
||||
'token': 'markup.inserted'
|
||||
},
|
||||
{
|
||||
'foreground': '176f2c',
|
||||
'background': 'f0fff4',
|
||||
'token': 'meta.diff.header.to-file'
|
||||
},
|
||||
{
|
||||
'foreground': '176f2c',
|
||||
'background': 'f0fff4',
|
||||
'token': 'punctuation.definition.inserted'
|
||||
},
|
||||
{
|
||||
'foreground': 'b08800',
|
||||
'background': 'fffdef',
|
||||
'token': 'markup.changed'
|
||||
},
|
||||
{
|
||||
'foreground': 'b08800',
|
||||
'background': 'fffdef',
|
||||
'token': 'punctuation.definition.changed'
|
||||
},
|
||||
{
|
||||
'foreground': '2f363d',
|
||||
'background': '959da5',
|
||||
'token': 'markup.ignored'
|
||||
},
|
||||
{
|
||||
'foreground': '2f363d',
|
||||
'background': '959da5',
|
||||
'token': 'markup.untracked'
|
||||
},
|
||||
{
|
||||
'foreground': 'b392f0',
|
||||
'fontStyle': 'bold',
|
||||
'token': 'meta.diff.range'
|
||||
},
|
||||
{
|
||||
'foreground': 'c8e1ff',
|
||||
'token': 'meta.diff.header'
|
||||
},
|
||||
{
|
||||
'foreground': '0366d6',
|
||||
'fontStyle': 'bold',
|
||||
'token': 'meta.separator'
|
||||
},
|
||||
{
|
||||
'foreground': '0366d6',
|
||||
'token': 'meta.output'
|
||||
},
|
||||
{
|
||||
'foreground': 'ffeef0',
|
||||
'token': 'brackethighlighter.tag'
|
||||
},
|
||||
{
|
||||
'foreground': 'ffeef0',
|
||||
'token': 'brackethighlighter.curly'
|
||||
},
|
||||
{
|
||||
'foreground': 'ffeef0',
|
||||
'token': 'brackethighlighter.round'
|
||||
},
|
||||
{
|
||||
'foreground': 'ffeef0',
|
||||
'token': 'brackethighlighter.square'
|
||||
},
|
||||
{
|
||||
'foreground': 'ffeef0',
|
||||
'token': 'brackethighlighter.angle'
|
||||
},
|
||||
{
|
||||
'foreground': 'ffeef0',
|
||||
'token': 'brackethighlighter.quote'
|
||||
},
|
||||
{
|
||||
'foreground': 'd73a49',
|
||||
'token': 'brackethighlighter.unmatched'
|
||||
},
|
||||
{
|
||||
'foreground': 'd73a49',
|
||||
'token': 'sublimelinter.mark.error'
|
||||
},
|
||||
{
|
||||
'foreground': 'fb8532',
|
||||
'token': 'sublimelinter.mark.warning'
|
||||
},
|
||||
{
|
||||
'foreground': '6a737d',
|
||||
'token': 'sublimelinter.gutter-mark'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'fontStyle': 'underline',
|
||||
'token': 'constant.other.reference.link'
|
||||
},
|
||||
{
|
||||
'foreground': '79b8ff',
|
||||
'fontStyle': 'underline',
|
||||
'token': 'string.other.link'
|
||||
}
|
||||
],
|
||||
'colors': {
|
||||
'editor.foreground': '#f6f8fa',
|
||||
'editor.background': editorBackground,
|
||||
'editor.selectionBackground': '#4c2889',
|
||||
'editor.inactiveSelectionBackground': '#444d56',
|
||||
'editor.lineHighlightBackground': '#444d56',
|
||||
'editorCursor.foreground': '#ffffff',
|
||||
'editorWhitespace.foreground': '#6a737d',
|
||||
'editorIndentGuide.background': '#6a737d',
|
||||
'editorIndentGuide.activeBackground': '#f6f8fa',
|
||||
'editor.selectionHighlightBorder': '#444d56'
|
||||
}
|
||||
});
|
||||
|
||||
const editor = monaco.editor.create($refs.monacoEditorElement, {
|
||||
value: monacoContent,
|
||||
theme: editorTheme,
|
||||
theme: document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs',
|
||||
wordWrap: 'on',
|
||||
readOnly: '{{ $readonly ?? false }}',
|
||||
minimap: { enabled: false },
|
||||
@@ -399,7 +54,20 @@
|
||||
lineNumbersMinChars: 3,
|
||||
automaticLayout: true,
|
||||
language: '{{ $language }}'
|
||||
});
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.attributeName === 'class') {
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
monaco.editor.setTheme(isDark ? 'vs-dark' : 'vs');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
monacoEditor(editor);
|
||||
@@ -411,7 +79,6 @@
|
||||
|
||||
updatePlaceholder(editor.getValue());
|
||||
|
||||
// Watch for changes in monacoContent from Livewire
|
||||
$watch('monacoContent', value => {
|
||||
if (editor.getValue() !== value) {
|
||||
editor.setValue(value);
|
||||
|
||||
@@ -258,6 +258,7 @@
|
||||
<input type="text" x-model="confirmationText"
|
||||
class="p-2 pr-10 w-full text-black rounded cursor-text input" readonly>
|
||||
<button @click="copyConfirmationText()"
|
||||
x-show="window.isSecureContext"
|
||||
class="absolute right-2 top-1/2 text-gray-500 transform -translate-y-1/2 hover:text-gray-700"
|
||||
title="Copy confirmation text" x-ref="copyButton">
|
||||
<template x-if="!copied">
|
||||
|
||||
@@ -7,18 +7,22 @@
|
||||
href="{{ route('notifications.email') }}">
|
||||
<button>Email</button>
|
||||
</a>
|
||||
<a class="{{ request()->routeIs('notifications.telegram') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('notifications.telegram') }}">
|
||||
<button>Telegram</button>
|
||||
</a>
|
||||
<a class="{{ request()->routeIs('notifications.discord') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('notifications.discord') }}">
|
||||
<button>Discord</button>
|
||||
</a>
|
||||
<a class="{{ request()->routeIs('notifications.telegram') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('notifications.telegram') }}">
|
||||
<button>Telegram</button>
|
||||
</a>
|
||||
<a class="{{ request()->routeIs('notifications.slack') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('notifications.slack') }}">
|
||||
<button>Slack</button>
|
||||
</a>
|
||||
<a class="{{ request()->routeIs('notifications.pushover') ? 'dark:text-white' : '' }}"
|
||||
href="{{ route('notifications.pushover') }}">
|
||||
<button>Pushover</button>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
8
resources/views/emails/docker-cleanup-failed.blade.php
Normal file
8
resources/views/emails/docker-cleanup-failed.blade.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<x-emails.layout>
|
||||
Docker Cleanup on {{ $name }} FAILED with the following error:
|
||||
|
||||
<pre>
|
||||
{{ $text }}
|
||||
</pre>
|
||||
|
||||
</x-emails.layout>
|
||||
9
resources/views/emails/docker-cleanup-success.blade.php
Normal file
9
resources/views/emails/docker-cleanup-success.blade.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<x-emails.layout>
|
||||
Docker Cleanup on {{ $name }} succeeded with the following message:
|
||||
|
||||
|
||||
<pre>
|
||||
{{ $text }}
|
||||
</pre>
|
||||
|
||||
</x-emails.layout>
|
||||
9
resources/views/emails/scheduled-task-success.blade.php
Normal file
9
resources/views/emails/scheduled-task-success.blade.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<x-emails.layout>
|
||||
Scheduled task ({{ $task->name }}) completed successfully with the following output:
|
||||
|
||||
<pre>
|
||||
{{ $output }}
|
||||
</pre>
|
||||
|
||||
Click [here]({{ $url }}) to view the task.
|
||||
</x-emails.layout>
|
||||
@@ -1,7 +0,0 @@
|
||||
<x-emails.layout>
|
||||
Someone added this email to the Coolify Cloud's waitlist. [Click here]({{ $confirmation_url }}) to confirm!
|
||||
|
||||
The link will expire in {{ config('constants.waitlist.expiration') }} minutes.
|
||||
|
||||
You have no idea what [Coolify Cloud](https://coolify.io) is or this waitlist? [Click here]({{ $cancel_url }}) to remove you from the waitlist.
|
||||
</x-emails.layout>
|
||||
@@ -1,3 +0,0 @@
|
||||
<x-emails.layout>
|
||||
You have been invited to join the Coolify Cloud: [Get Started]({{ $loginLink }})
|
||||
</x-emails.layout>
|
||||
@@ -3,7 +3,7 @@
|
||||
Notifications | Coolify
|
||||
</x-slot>
|
||||
<x-notification.navbar />
|
||||
<form wire:submit='submit' class="flex flex-col gap-4">
|
||||
<form wire:submit='submit' class="flex flex-col gap-4 pb-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Discord</h2>
|
||||
<x-forms.button type="submit">
|
||||
@@ -12,7 +12,11 @@
|
||||
@if ($discordEnabled)
|
||||
<x-forms.button class="normal-case dark:text-white btn btn-xs no-animation btn-primary"
|
||||
wire:click="sendTestNotification">
|
||||
Send Test Notifications
|
||||
Send Test Notification
|
||||
</x-forms.button>
|
||||
@else
|
||||
<x-forms.button disabled class="normal-case dark:text-white btn btn-xs no-animation btn-primary">
|
||||
Send Test Notification
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
@@ -20,24 +24,58 @@
|
||||
<x-forms.checkbox instantSave="instantSaveDiscordEnabled" id="discordEnabled" label="Enabled" />
|
||||
</div>
|
||||
<x-forms.input type="password"
|
||||
helper="Generate a webhook in Discord.<br>Example: https://discord.com/api/webhooks/...." required
|
||||
helper="Create a Discord Server and generate a Webhook URL. <br><a class='inline-block underline dark:text-white' href='https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks' target='_blank'>Webhook Documentation</a>" required
|
||||
id="discordWebhookUrl" label="Webhook" />
|
||||
</form>
|
||||
@if ($discordEnabled)
|
||||
<h2 class="mt-4">Subscribe to events</h2>
|
||||
<div class="w-64">
|
||||
@if (isDev())
|
||||
<x-forms.checkbox instantSave="saveModel" id="discordNotificationsTest" label="Test" />
|
||||
@endif
|
||||
<x-forms.checkbox instantSave="saveModel" id="discordNotificationsStatusChanges"
|
||||
label="Container Status Changes" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="discordNotificationsDeployments"
|
||||
label="Application Deployments" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="discordNotificationsDatabaseBackups" label="Backup Status" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="discordNotificationsScheduledTasks"
|
||||
label="Scheduled Tasks Status" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="discordNotificationsServerDiskUsage"
|
||||
label="Server Disk Usage" />
|
||||
<h2 class="mt-4">Notification Settings</h2>
|
||||
<p class="mb-4">
|
||||
Select events for which you would like to receive Discord notifications.
|
||||
</p>
|
||||
<div class="flex flex-col gap-4 max-w-2xl">
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Deployments</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentSuccessDiscordNotifications"
|
||||
label="Deployment Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentFailureDiscordNotifications"
|
||||
label="Deployment Failure" />
|
||||
<x-forms.checkbox instantSave="saveModel"
|
||||
helper="Send a notification when a container status changes. It will notify for Stopped and Restarted events of a container."
|
||||
id="statusChangeDiscordNotifications" label="Container Status Changes" />
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Backups</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupSuccessDiscordNotifications"
|
||||
label="Backup Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupFailureDiscordNotifications"
|
||||
label="Backup Failure" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Scheduled Tasks</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskSuccessDiscordNotifications"
|
||||
label="Scheduled Task Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskFailureDiscordNotifications"
|
||||
label="Scheduled Task Failure" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Server</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupSuccessDiscordNotifications"
|
||||
label="Docker Cleanup Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupFailureDiscordNotifications"
|
||||
label="Docker Cleanup Failure" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverDiskUsageDiscordNotifications"
|
||||
label="Server Disk Usage" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverReachableDiscordNotifications"
|
||||
label="Server Reachable" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverUnreachableDiscordNotifications"
|
||||
label="Server Unreachable" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,26 +9,27 @@
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if (isInstanceAdmin() && !$useInstanceEmailSettings)
|
||||
<x-forms.button wire:click='copyFromInstanceSettings'>
|
||||
Copy from Instance Settings
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@if (isEmailEnabled($team) && auth()->user()->isAdminFromSession() && isTestEmailEnabled($team))
|
||||
<x-modal-input buttonTitle="Send Test Email" title="Send Test Email">
|
||||
<form wire:submit.prevent="sendTestEmail" class="flex flex-col w-full gap-2">
|
||||
<x-forms.input wire:model="testEmailAddress" placeholder="test@example.com" id="testEmailAddress"
|
||||
label="Recipients" required />
|
||||
<x-forms.button type="submit" @click="modalOpen=false">
|
||||
Send Email
|
||||
</x-forms.button>
|
||||
</form>
|
||||
</x-modal-input>
|
||||
@if (auth()->user()->isAdminFromSession())
|
||||
@if ($team->isNotificationEnabled('email'))
|
||||
<x-modal-input buttonTitle="Send Test Email" title="Send Test Email">
|
||||
<form wire:submit.prevent="sendTestEmail" class="flex flex-col w-full gap-2">
|
||||
<x-forms.input wire:model="testEmailAddress" placeholder="test@example.com"
|
||||
id="testEmailAddress" label="Recipients" required />
|
||||
<x-forms.button type="submit" @click="modalOpen=false">
|
||||
Send Email
|
||||
</x-forms.button>
|
||||
</form>
|
||||
</x-modal-input>
|
||||
@else
|
||||
<x-forms.button disabled class="normal-case dark:text-white btn btn-xs no-animation btn-primary">
|
||||
Send Test Email
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
@if (!isCloud())
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="instantSaveInstance" id="useInstanceEmailSettings"
|
||||
<x-forms.checkbox instantSave="instantSave()" id="useInstanceEmailSettings"
|
||||
label="Use system wide (transactional) email settings" />
|
||||
</div>
|
||||
@endif
|
||||
@@ -38,17 +39,22 @@
|
||||
<x-forms.input required id="smtpFromAddress" helper="Email address used in emails."
|
||||
label="From Address" />
|
||||
</div>
|
||||
@if (isInstanceAdmin() && !$useInstanceEmailSettings)
|
||||
<x-forms.button wire:click='copyFromInstanceSettings'>
|
||||
Copy from Instance Settings
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@endif
|
||||
</form>
|
||||
@if (isCloud())
|
||||
<div class="w-64 py-4">
|
||||
<x-forms.checkbox instantSave="instantSaveInstance" id="useInstanceEmailSettings"
|
||||
<x-forms.checkbox instantSave="instantSave()" id="useInstanceEmailSettings"
|
||||
label="Use Hosted Email Service" />
|
||||
</div>
|
||||
@endif
|
||||
@if (!$useInstanceEmailSettings)
|
||||
<div class="flex flex-col gap-4">
|
||||
<form wire:submit='submit' class="p-4 border dark:border-coolgray-300 flex flex-col gap-2">
|
||||
<form wire:submit='submitSmtp' class="p-4 border dark:border-coolgray-300 flex flex-col gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<h3>SMTP Server</h3>
|
||||
<x-forms.button type="submit">
|
||||
@@ -56,7 +62,8 @@
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave="instantSaveSmtpEnabled" id="smtpEnabled" label="Enabled" />
|
||||
<x-forms.checkbox wire:model="smtpEnabled" instantSave="instantSave('SMTP')" id="smtpEnabled"
|
||||
label="Enabled" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col gap-4">
|
||||
@@ -78,7 +85,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form wire:submit='submit' class="p-4 border dark:border-coolgray-300 flex flex-col gap-2">
|
||||
<form wire:submit='submitResend' class="p-4 border dark:border-coolgray-300 flex flex-col gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<h3>Resend</h3>
|
||||
<x-forms.button type="submit">
|
||||
@@ -86,7 +93,8 @@
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave='instantSaveResend' id="resendEnabled" label="Enabled" />
|
||||
<x-forms.checkbox wire:model="resendEnabled" instantSave="instantSave('Resend')" id="resendEnabled"
|
||||
label="Enabled" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col gap-4">
|
||||
@@ -99,20 +107,55 @@
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
@if (isEmailEnabled($team) || $useInstanceEmailSettings)
|
||||
<h2 class="mt-4">Subscribe to events</h2>
|
||||
<div class="w-64">
|
||||
@if (isDev())
|
||||
<x-forms.checkbox instantSave="saveModel" id="smtpNotificationsTest" label="Test" />
|
||||
@endif
|
||||
<x-forms.checkbox instantSave="saveModel" id="smtpNotificationsStatusChanges"
|
||||
label="Container Status Changes" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="smtpNotificationsDeployments"
|
||||
label="Application Deployments" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="smtpNotificationsDatabaseBackups" label="Backup Status" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="smtpNotificationsScheduledTasks"
|
||||
label="Scheduled Tasks Status" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="smtpNotificationsServerDiskUsage" label="Server Disk Usage" />
|
||||
<h2 class="mt-4">Notification Settings</h2>
|
||||
<p class="mb-4">
|
||||
Select events for which you would like to receive email notifications.
|
||||
</p>
|
||||
<div class="flex flex-col gap-4 max-w-2xl">
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Deployments</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentSuccessEmailNotifications"
|
||||
label="Deployment Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentFailureEmailNotifications"
|
||||
label="Deployment Failure" />
|
||||
<x-forms.checkbox instantSave="saveModel"
|
||||
helper="Send an email when a container status changes. It will send and email for Stopped and Restarted events of a container."
|
||||
id="statusChangeEmailNotifications" label="Container Status Changes" />
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Backups</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupSuccessEmailNotifications"
|
||||
label="Backup Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupFailureEmailNotifications"
|
||||
label="Backup Failure" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Scheduled Tasks</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskSuccessEmailNotifications"
|
||||
label="Scheduled Task Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskFailureEmailNotifications"
|
||||
label="Scheduled Task Failure" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Server</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupSuccessEmailNotifications"
|
||||
label="Docker Cleanup Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupFailureEmailNotifications"
|
||||
label="Docker Cleanup Failure" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverDiskUsageEmailNotifications"
|
||||
label="Server Disk Usage" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverReachableEmailNotifications"
|
||||
label="Server Reachable" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverUnreachableEmailNotifications"
|
||||
label="Server Unreachable" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
86
resources/views/livewire/notifications/pushover.blade.php
Normal file
86
resources/views/livewire/notifications/pushover.blade.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Notifications | Coolify
|
||||
</x-slot>
|
||||
<x-notification.navbar />
|
||||
<form wire:submit='submit' class="flex flex-col gap-4 pb-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Pushover</h2>
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if ($pushoverEnabled)
|
||||
<x-forms.button class="normal-case dark:text-white btn btn-xs no-animation btn-primary"
|
||||
wire:click="sendTestNotification">
|
||||
Send Test Notification
|
||||
</x-forms.button>
|
||||
@else
|
||||
<x-forms.button disabled class="normal-case dark:text-white btn btn-xs no-animation btn-primary">
|
||||
Send Test Notification
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave="instantSavePushoverEnabled" id="pushoverEnabled" label="Enabled" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input type="password"
|
||||
helper="Get your User Key in Pushover. You need to be logged in to Pushover to see your user key in the top right corner. <br><a class='inline-block underline dark:text-white' href='https://pushover.net/' target='_blank'>Pushover Dashboard</a>"
|
||||
required id="pushoverUserKey" label="User Key" />
|
||||
<x-forms.input type="password"
|
||||
helper="Generate an API Token/Key in Pushover by creating a new application. <br><a class='inline-block underline dark:text-white' href='https://pushover.net/apps/build' target='_blank'>Create Pushover Application</a>"
|
||||
required id="pushoverApiToken" label="API Token" />
|
||||
</div>
|
||||
</form>
|
||||
<h2 class="mt-4">Notification Settings</h2>
|
||||
<p class="mb-4">
|
||||
Select events for which you would like to receive Pushover notifications.
|
||||
</p>
|
||||
<div class="flex flex-col gap-4 max-w-2xl">
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Deployments</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentSuccessPushoverNotifications"
|
||||
label="Deployment Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentFailurePushoverNotifications"
|
||||
label="Deployment Failure" />
|
||||
<x-forms.checkbox instantSave="saveModel"
|
||||
helper="Send a notification when a container status changes. It will notify for Stopped and Restarted events of a container."
|
||||
id="statusChangePushoverNotifications" label="Container Status Changes" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Backups</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupSuccessPushoverNotifications"
|
||||
label="Backup Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupFailurePushoverNotifications"
|
||||
label="Backup Failure" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Scheduled Tasks</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskSuccessPushoverNotifications"
|
||||
label="Scheduled Task Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskFailurePushoverNotifications"
|
||||
label="Scheduled Task Failure" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Server</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupSuccessPushoverNotifications"
|
||||
label="Docker Cleanup Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupFailurePushoverNotifications"
|
||||
label="Docker Cleanup Failure" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverDiskUsagePushoverNotifications"
|
||||
label="Server Disk Usage" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverReachablePushoverNotifications"
|
||||
label="Server Reachable" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverUnreachablePushoverNotifications"
|
||||
label="Server Unreachable" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,43 +1,79 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Notifications | Coolify
|
||||
</x-slot>
|
||||
<x-notification.navbar />
|
||||
<form wire:submit='submit' class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Slack</h2>
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-slot>
|
||||
<x-notification.navbar />
|
||||
<form wire:submit='submit' class="flex flex-col gap-4 pb-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Slack</h2>
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if ($slackEnabled)
|
||||
<x-forms.button class="normal-case dark:text-white btn btn-xs no-animation btn-primary"
|
||||
wire:click="sendTestNotification">
|
||||
Send Test Notification
|
||||
</x-forms.button>
|
||||
@if ($slackEnabled)
|
||||
<x-forms.button class="normal-case dark:text-white btn btn-xs no-animation btn-primary"
|
||||
wire:click="sendTestNotification">
|
||||
Send Test Notifications
|
||||
</x-forms.button>
|
||||
@endif
|
||||
@else
|
||||
<x-forms.button disabled class="normal-case dark:text-white btn btn-xs no-animation btn-primary">
|
||||
Send Test Notification
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave="instantSaveSlackEnabled" id="slackEnabled" label="Enabled" />
|
||||
</div>
|
||||
<x-forms.input type="password"
|
||||
helper="Create a Slack APP and generate a Incoming Webhook URL. <br><a class='inline-block underline dark:text-white' href='https://api.slack.com/apps' target='_blank'>Create Slack APP</a>" required
|
||||
id="slackWebhookUrl" label="Webhook" />
|
||||
</form>
|
||||
<h2 class="mt-4">Notification Settings</h2>
|
||||
<p class="mb-4">
|
||||
Select events for which you would like to receive Slack notifications.
|
||||
</p>
|
||||
<div class="flex flex-col gap-4 max-w-2xl">
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Deployments</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentSuccessSlackNotifications"
|
||||
label="Deployment Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentFailureSlackNotifications"
|
||||
label="Deployment Failure" />
|
||||
<x-forms.checkbox instantSave="saveModel"
|
||||
helper="Send a notification when a container status changes. It will notify for Stopped and Restarted events of a container."
|
||||
id="statusChangeSlackNotifications" label="Container Status Changes" />
|
||||
</div>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave="instantSaveSlackEnabled" id="slackEnabled" label="Enabled" />
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Backups</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupSuccessSlackNotifications" label="Backup Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupFailureSlackNotifications" label="Backup Failure" />
|
||||
</div>
|
||||
<x-forms.input type="password"
|
||||
helper="Generate a webhook in Slack.<br>Example: https://hooks.slack.com/services/...." required
|
||||
id="slackWebhookUrl" label="Webhook" />
|
||||
</form>
|
||||
@if ($slackEnabled)
|
||||
<h2 class="mt-4">Subscribe to events</h2>
|
||||
<div class="w-64">
|
||||
@if (isDev())
|
||||
<x-forms.checkbox instantSave="saveModel" id="slackNotificationsTest" label="Test" />
|
||||
@endif
|
||||
<x-forms.checkbox instantSave="saveModel" id="slackNotificationsStatusChanges"
|
||||
label="Container Status Changes" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="slackNotificationsDeployments"
|
||||
label="Application Deployments" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="slackNotificationsDatabaseBackups" label="Backup Status" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="slackNotificationsScheduledTasks"
|
||||
label="Scheduled Tasks Status" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="slackNotificationsServerDiskUsage"
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Scheduled Tasks</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskSuccessSlackNotifications"
|
||||
label="Scheduled Task Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskFailureSlackNotifications"
|
||||
label="Scheduled Task Failure" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="font-medium mb-3">Server</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupSuccessSlackNotifications"
|
||||
label="Docker Cleanup Success" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupFailureSlackNotifications"
|
||||
label="Docker Cleanup Failure" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverDiskUsageSlackNotifications"
|
||||
label="Server Disk Usage" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverReachableSlackNotifications"
|
||||
label="Server Reachable" />
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverUnreachableSlackNotifications"
|
||||
label="Server Unreachable" />
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Notifications | Coolify
|
||||
</x-slot>
|
||||
<x-notification.navbar />
|
||||
<form wire:submit='submit' class="flex flex-col gap-4">
|
||||
<form wire:submit='submit' class="flex flex-col gap-4 pb-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Telegram</h2>
|
||||
<x-forms.button type="submit">
|
||||
@@ -12,7 +12,11 @@
|
||||
@if ($telegramEnabled)
|
||||
<x-forms.button class="normal-case dark:text-white btn btn-xs no-animation btn-primary"
|
||||
wire:click="sendTestNotification">
|
||||
Send Test Notifications
|
||||
Send Test Notification
|
||||
</x-forms.button>
|
||||
@else
|
||||
<x-forms.button disabled class="normal-case dark:text-white btn btn-xs no-animation btn-primary">
|
||||
Send Test Notification
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
@@ -20,61 +24,143 @@
|
||||
<x-forms.checkbox instantSave="instantSaveTelegramEnabled" id="telegramEnabled" label="Enabled" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
|
||||
<x-forms.input type="password" autocomplete="new-password"
|
||||
helper="Get it from the <a class='inline-block underline dark:text-white' href='https://t.me/botfather' target='_blank'>BotFather Bot</a> on Telegram."
|
||||
required id="telegramToken" label="Token" />
|
||||
<x-forms.input helper="Recommended to add your bot to a group chat and add its Chat ID here." required
|
||||
required id="telegramToken" label="Bot API Token" />
|
||||
<x-forms.input type="password" autocomplete="new-password" helper="Add your bot to a group chat and add its Chat ID here." required
|
||||
id="telegramChatId" label="Chat ID" />
|
||||
</div>
|
||||
@if ($telegramEnabled)
|
||||
<h2 class="mt-4">Subscribe to events</h2>
|
||||
<div class="flex flex-col gap-4 w-96">
|
||||
@if (isDev())
|
||||
<div class="flex flex-col">
|
||||
<h4>Test Notification</h4>
|
||||
<x-forms.checkbox instantSave="saveModel" id="telegramNotificationsTest" label="Enabled" />
|
||||
<x-forms.input
|
||||
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
|
||||
id="telegramNotificationsTestMessageThreadId" label="Custom Topic ID" />
|
||||
</form>
|
||||
<h2 class="mt-4">Notification Settings</h2>
|
||||
<p class="mb-4">
|
||||
Select events for which you would like to receive Telegram notifications.
|
||||
</p>
|
||||
<div class="flex flex-col gap-4 ">
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="text-lg font-medium mb-3">Deployments</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentSuccessTelegramNotifications"
|
||||
label="Deployment Success" />
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex flex-col">
|
||||
<h4>Container Status Changes</h4>
|
||||
<x-forms.checkbox instantSave="saveModel" id="telegramNotificationsStatusChanges" label="Enabled" />
|
||||
<x-forms.input
|
||||
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
|
||||
id="telegramNotificationsStatusChangesMessageThreadId" label="Custom Topic ID" />
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsDeploymentSuccessThreadId" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h4>Application Deployments</h4>
|
||||
<x-forms.checkbox instantSave="saveModel" id="telegramNotificationsDeployments" label="Enabled" />
|
||||
<x-forms.input
|
||||
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
|
||||
id="telegramNotificationsDeploymentsMessageThreadId" label="Custom Topic ID" />
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="deploymentFailureTelegramNotifications"
|
||||
label="Deployment Failure" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsDeploymentFailureThreadId" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h4>Database Backup Status</h4>
|
||||
<x-forms.checkbox instantSave="saveModel" id="telegramNotificationsDatabaseBackups"
|
||||
label="Enabled" />
|
||||
<x-forms.input
|
||||
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
|
||||
id="telegramNotificationsDatabaseBackupsMessageThreadId" label="Custom Topic ID" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h4>Scheduled Tasks Status</h4>
|
||||
<x-forms.checkbox instantSave="saveModel" id="telegramNotificationsScheduledTasks"
|
||||
label="Enabled" />
|
||||
<x-forms.input
|
||||
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
|
||||
id="telegramNotificationsScheduledTasksMessageThreadId" label="Custom Topic ID" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h4>Server Disk Usage</h4>
|
||||
<x-forms.checkbox instantSave="saveModel" id="telegramNotificationsServerDiskUsage"
|
||||
label="Enabled" />
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="statusChangeTelegramNotifications"
|
||||
label="Container Status Changes"
|
||||
helper="Send a notification when a container status changes. It will send a notification for Stopped and Restarted events of a container." />
|
||||
</div>
|
||||
<x-forms.input type="password" id="telegramNotificationsStatusChangeThreadId"
|
||||
placeholder="Custom Telegram Thread ID" />
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="text-lg font-medium mb-3">Backups</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupSuccessTelegramNotifications"
|
||||
label="Backup Success" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsBackupSuccessThreadId" />
|
||||
</div>
|
||||
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="backupFailureTelegramNotifications"
|
||||
label="Backup Failure" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsBackupFailureThreadId" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="text-lg font-medium mb-3">Scheduled Tasks</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskSuccessTelegramNotifications"
|
||||
label="Scheduled Task Success" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsScheduledTaskSuccessThreadId" />
|
||||
</div>
|
||||
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="scheduledTaskFailureTelegramNotifications"
|
||||
label="Scheduled Task Failure" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsScheduledTaskFailureThreadId" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border dark:border-coolgray-300 p-4 rounded-lg">
|
||||
<h3 class="text-lg font-medium mb-3">Server</h3>
|
||||
<div class="flex flex-col gap-1.5 pl-1">
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupSuccessTelegramNotifications"
|
||||
label="Docker Cleanup Success" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsDockerCleanupSuccessThreadId" />
|
||||
</div>
|
||||
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="dockerCleanupFailureTelegramNotifications"
|
||||
label="Docker Cleanup Failure" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsDockerCleanupFailureThreadId" />
|
||||
</div>
|
||||
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverDiskUsageTelegramNotifications"
|
||||
label="Server Disk Usage" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsServerDiskUsageThreadId" />
|
||||
</div>
|
||||
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverReachableTelegramNotifications"
|
||||
label="Server Reachable" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsServerReachableThreadId" />
|
||||
</div>
|
||||
|
||||
|
||||
<div class="pl-1 flex gap-2">
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox instantSave="saveModel" id="serverUnreachableTelegramNotifications"
|
||||
label="Server Unreachable" />
|
||||
</div>
|
||||
<x-forms.input type="password" placeholder="Custom Telegram Thread ID"
|
||||
id="telegramNotificationsServerUnreachableThreadId" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
class="font-mono pr-10"
|
||||
/>
|
||||
<button
|
||||
x-show="window.isSecureContext"
|
||||
@click="navigator.clipboard.writeText(secretKey); copiedSecretKey = true; setTimeout(() => copiedSecretKey = false, 2000)"
|
||||
class="absolute right-2 bottom-1 p-1 rounded hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
>
|
||||
@@ -78,6 +79,7 @@
|
||||
class="font-mono pr-10"
|
||||
/>
|
||||
<button
|
||||
x-show="window.isSecureContext"
|
||||
@click="navigator.clipboard.writeText(otpUrl); copiedOtpUrl = true; setTimeout(() => copiedOtpUrl = false, 2000)"
|
||||
class="absolute right-2 bottom-1 p-1 rounded hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
>
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<option value="non-www">Redirect to non-www.</option>
|
||||
</x-forms.select>
|
||||
<x-modal-confirmation title="Confirm Redirection Setting?" buttonTitle="Set Direction"
|
||||
submitAction="set_redirect" :actions="['All traffic will be redirected to the selected direction.']" confirmationText="{{ $application->fqdn . '/' }}"
|
||||
submitAction="setRedirect" :actions="['All traffic will be redirected to the selected direction.']" confirmationText="{{ $application->fqdn . '/' }}"
|
||||
confirmationLabel="Please confirm the execution of the action by entering the Application URL below"
|
||||
shortConfirmationLabel="Application URL" :confirmWithPassword="false" step2ButtonText="Set Direction">
|
||||
<x-slot:customButton>
|
||||
@@ -161,8 +161,7 @@
|
||||
</div>
|
||||
<div class="pt-1 text-xs">Nixpacks will detect the required configuration
|
||||
automatically.
|
||||
<a class="underline"
|
||||
href="https://coolify.io/docs/applications">Framework
|
||||
<a class="underline" href="https://coolify.io/docs/applications">Framework
|
||||
Specific Docs</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</nav>
|
||||
@if ($service->isDeployable)
|
||||
<div class="flex flex-wrap order-first gap-2 items-center sm:order-last">
|
||||
@if (str($service->status())->contains('running'))
|
||||
@if (str($service->status)->contains('running'))
|
||||
<x-dropdown>
|
||||
<x-slot:title>
|
||||
Advanced
|
||||
@@ -70,7 +70,7 @@
|
||||
Stop
|
||||
</x-slot:button-title>
|
||||
</x-modal-confirmation>
|
||||
@elseif (str($service->status())->contains('degraded'))
|
||||
@elseif (str($service->status)->contains('degraded'))
|
||||
<button @click="$wire.dispatch('startEvent')" class="gap-2 button">
|
||||
<svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
@@ -99,7 +99,7 @@
|
||||
Stop
|
||||
</x-slot:button-title>
|
||||
</x-modal-confirmation>
|
||||
@elseif (str($service->status())->contains('exited'))
|
||||
@elseif (str($service->status)->contains('exited'))
|
||||
<button wire:click='stop(true)' class="gap-2 button">
|
||||
<svg class="w-5 h-5" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="red" d="M26 20h-6v-2h6zm4 8h-6v-2h6zm-2-4h-6v-2h6z" />
|
||||
@@ -150,8 +150,7 @@
|
||||
@else
|
||||
<div class="flex flex-wrap order-first gap-2 items-center sm:order-last">
|
||||
<div class="text-error">
|
||||
Unable to deploy. <a
|
||||
class="underline font-bold cursor-pointer"
|
||||
Unable to deploy. <a class="underline font-bold cursor-pointer"
|
||||
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'">
|
||||
Required environment variables missing.</a>
|
||||
</div>
|
||||
|
||||
@@ -9,17 +9,27 @@
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if (is_transactional_emails_enabled() && auth()->user()->isAdminFromSession())
|
||||
<x-modal-input buttonTitle="Send Test Email" title="Send Test Email">
|
||||
<form wire:submit.prevent="sendTestEmail" class="flex flex-col w-full gap-2">
|
||||
<x-forms.input wire:model="testEmailAddress" placeholder="test@example.com" id="testEmailAddress"
|
||||
label="Recipients" required />
|
||||
<x-forms.button type="submit" @click="modalOpen=false">
|
||||
Send Email
|
||||
</x-forms.button>
|
||||
</form>
|
||||
</x-modal-input>
|
||||
@endif
|
||||
</div>
|
||||
<div class="pb-4 ">Email settings for password resets, invitations, etc.</div>
|
||||
<div class="flex gap-4">
|
||||
<div class="pb-4">Instance wide email settings for password resets, invitations, etc.</div>
|
||||
<div class="flex gap-4">
|
||||
<x-forms.input required id="smtpFromName" helper="Name used in emails." label="From Name" />
|
||||
<x-forms.input required id="smtpFromAddress" helper="Email address used in emails." label="From Address" />
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="p-4 border dark:border-coolgray-300">
|
||||
<form wire:submit='submit' class="flex flex-col">
|
||||
<form wire:submit.prevent="submitSmtp" class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h3>SMTP Server</h3>
|
||||
<x-forms.button type="submit">
|
||||
@@ -49,7 +59,7 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="p-4 border dark:border-coolgray-300">
|
||||
<form wire:submit='submit' class="flex flex-col">
|
||||
<form wire:submit.prevent="submitResend" class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h3>Resend</h3>
|
||||
<x-forms.button type="submit">
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
<div class="flex flex-col gap-2 pt-4">
|
||||
@foreach ($oauth_settings_map as $oauth_setting)
|
||||
<div class="p-4 border dark:border-coolgray-300">
|
||||
<h3>{{ ucfirst($oauth_setting->provider) }} Oauth</h3>
|
||||
<h3>{{ ucfirst($oauth_setting->provider) }}</h3>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave id="oauth_settings_map.{{ $oauth_setting->provider }}.enabled"
|
||||
label="Enabled" />
|
||||
<x-forms.checkbox instantSave="instantSave('{{ $oauth_setting->provider }}')"
|
||||
id="oauth_settings_map.{{ $oauth_setting->provider }}.enabled" label="Enabled" />
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input id="oauth_settings_map.{{ $oauth_setting->provider }}.client_id"
|
||||
@@ -32,6 +32,10 @@
|
||||
<x-forms.input id="oauth_settings_map.{{ $oauth_setting->provider }}.tenant"
|
||||
label="Tenant" />
|
||||
@endif
|
||||
@if ($oauth_setting->provider == 'authentik')
|
||||
<x-forms.input id="oauth_settings_map.{{ $oauth_setting->provider }}.base_url"
|
||||
label="Base URL" />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<x-modal-confirmation title="Disable Two Step Confirmation?"
|
||||
buttonTitle="Disable Two Step Confirmation" isErrorButton
|
||||
submitAction="toggleTwoStepConfirmation" :actions="[
|
||||
'Tow Step confimation will be disabled globally.',
|
||||
'Two Step confimation will be disabled globally.',
|
||||
'Disabling two step confirmation reduces security (as anyone can easily delete anything).',
|
||||
'The risk of accidental actions will increase.',
|
||||
]"
|
||||
|
||||
@@ -2,42 +2,38 @@
|
||||
<x-slot:title>
|
||||
Subscribe | Coolify
|
||||
</x-slot>
|
||||
@if ($settings->is_resale_license_active)
|
||||
@if (auth()->user()->isAdminFromSession())
|
||||
<div>
|
||||
<div class="flex gap-2">
|
||||
<h1>Subscriptions</h1>
|
||||
@if (subscriptionProvider() === 'stripe' && $alreadySubscribed)
|
||||
<x-forms.button wire:click='stripeCustomerPortal'>Manage My Subscription</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
@if (request()->query->get('cancelled'))
|
||||
<div class="mb-6 rounded alert-error">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span>Something went wrong with your subscription. Please try again or contact
|
||||
support.</span>
|
||||
</div>
|
||||
@if (auth()->user()->isAdminFromSession())
|
||||
<div>
|
||||
<div class="flex gap-2">
|
||||
<h1>Subscriptions</h1>
|
||||
@if (subscriptionProvider() === 'stripe' && $alreadySubscribed)
|
||||
<x-forms.button wire:click='stripeCustomerPortal'>Manage My Subscription</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
@if (request()->query->get('cancelled'))
|
||||
<div class="mb-6 rounded alert-error">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span>Something went wrong with your subscription. Please try again or contact
|
||||
support.</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (config('subscription.provider') === 'stripe')
|
||||
<livewire:subscription.pricing-plans />
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<div class="flex flex-col justify-center mx-10">
|
||||
<div class="flex gap-2">
|
||||
<h1>Subscription</h1>
|
||||
</div>
|
||||
<div>You are not an admin or have been removed from this team. If this does not make sense, please <span
|
||||
class="underline cursor-pointer dark:text-white" wire:click="help">contact
|
||||
us</span>.</div>
|
||||
</div>
|
||||
@endif
|
||||
@if (config('subscription.provider') === 'stripe')
|
||||
<livewire:subscription.pricing-plans />
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<div class="px-10">Resale license is not active. Please contact your instance admin.</div>
|
||||
<div class="flex flex-col justify-center mx-10">
|
||||
<div class="flex gap-2">
|
||||
<h1>Subscription</h1>
|
||||
</div>
|
||||
<div>You are not an admin or have been removed from this team. If this does not make sense, please <span
|
||||
class="underline cursor-pointer dark:text-white" wire:click="help">contact
|
||||
us</span>.</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.button type="submit">Generate Invitation Link</x-forms.button>
|
||||
@if (is_transactional_emails_active())
|
||||
@if (is_transactional_emails_enabled())
|
||||
<x-forms.button wire:click.prevent='viaEmail'>Send Invitation via Email</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</div>
|
||||
@if (auth()->user()->isAdminFromSession())
|
||||
<div class="py-4">
|
||||
@if (is_transactional_emails_active())
|
||||
@if (is_transactional_emails_enabled())
|
||||
<h2 class="pb-4">Invite New Member</h2>
|
||||
@else
|
||||
<h2>Invite New Member</h2>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<div class="min-h-screen hero">
|
||||
<div class="w-96 min-w-fit">
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<a href="{{ route('dashboard') }}">
|
||||
<div class="text-5xl font-bold tracking-tight text-center dark:text-white">Coolify</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex items-center justify-center pb-4 text-center">
|
||||
<h2>Self-hosting in the cloud
|
||||
<svg class="inline-block w-8 h-8 dark:text-warning width="512" height="512" viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="currentColor" fill-rule="evenodd" clip-rule="evenodd">
|
||||
<path
|
||||
d="M13 4h-1a4.002 4.002 0 0 0-3.874 3H8a4 4 0 1 0 0 8h8a4 4 0 0 0 .899-7.899A4.002 4.002 0 0 0 13 4Z"
|
||||
opacity=".2" />
|
||||
<path
|
||||
d="M11 3h-1a4.002 4.002 0 0 0-3.874 3H6a4 4 0 1 0 0 8h8a4 4 0 0 0 .899-7.899A4.002 4.002 0 0 0 11 3ZM6.901 7l.193-.75A3.002 3.002 0 0 1 10 4h1c1.405 0 2.614.975 2.924 2.325l.14.61l.61.141A3.001 3.001 0 0 1 14 13H6a3 3 0 1 1 0-6h.901Z" />
|
||||
</g>
|
||||
</svg>
|
||||
</h2>
|
||||
</div>
|
||||
<form class="flex items-end gap-2" wire:submit='submit'>
|
||||
<x-forms.input id="email" type="email" label="Email" placeholder="youareawesome@protonmail.com" />
|
||||
<x-forms.button type="submit">Join Waitlist</x-forms.button>
|
||||
</form>
|
||||
<div>People waiting in the line: <span class="font-bold dark:text-warning">{{ $waitingInLine }}</div>
|
||||
<div>Already using Coolify Cloud: <span class="font-bold dark:text-warning">{{ $users }}</div>
|
||||
<div class="pt-8">
|
||||
This is a paid & hosted version of Coolify.<br> See the pricing <a href="https://coolify.io/pricing"
|
||||
class="dark:text-warning">here</a>.
|
||||
</div>
|
||||
<div class="pt-4">
|
||||
If you are looking for the self-hosted version go <a href="https://coolify.io"
|
||||
class="dark:text-warning">here</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user