mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 15:02:34 +00:00
Merge (#127)
This commit is contained in:
@ -0,0 +1,5 @@
|
||||
<x-profile-layout>
|
||||
<x-slot name="pageTitle">{{ __("Notification Channels") }}</x-slot>
|
||||
|
||||
@include("settings.notification-channels.partials.channels-list")
|
||||
</x-profile-layout>
|
@ -0,0 +1,114 @@
|
||||
<div>
|
||||
<x-primary-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'add-channel')">
|
||||
{{ __("Add new Channel") }}
|
||||
</x-primary-button>
|
||||
|
||||
<x-modal name="add-channel">
|
||||
@php
|
||||
$oldProvider = old("provider", request()->input("provider") ?? "");
|
||||
@endphp
|
||||
|
||||
<form
|
||||
id="add-channel-form"
|
||||
hx-post="{{ route("notification-channels.add") }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#add-channel-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-add-channel"
|
||||
class="p-6"
|
||||
x-data="{ provider: '{{ $oldProvider }}' }"
|
||||
>
|
||||
@csrf
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Add new Channel") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="provider" value="Provider" />
|
||||
<x-select-input x-model="provider" id="provider" name="provider" class="mt-1 w-full">
|
||||
<option value="" selected disabled>
|
||||
{{ __("Select") }}
|
||||
</option>
|
||||
@foreach (config("core.notification_channels_providers") as $p)
|
||||
@if ($p !== "custom")
|
||||
<option value="{{ $p }}" @if ($oldProvider === $p) selected @endif>
|
||||
{{ $p }}
|
||||
</option>
|
||||
@endif
|
||||
@endforeach
|
||||
</x-select-input>
|
||||
@error("provider")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="label" :value="__('Label')" />
|
||||
<x-text-input value="{{ old('label') }}" id="label" name="label" type="text" class="mt-1 w-full" />
|
||||
@error("label")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="provider === 'email'" class="mt-6">
|
||||
<x-input-label for="email" :value="__('Email')" />
|
||||
<x-text-input value="{{ old('email') }}" id="email" name="email" type="text" class="mt-1 w-full" />
|
||||
@error("email")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="['slack', 'discord'].includes(provider)" class="mt-6">
|
||||
<x-input-label for="webhook_url" :value="__('Webhook URL')" />
|
||||
<x-text-input
|
||||
value="{{ old('webhook_url') }}"
|
||||
id="webhook_url"
|
||||
name="webhook_url"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("webhook_url")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="provider === 'telegram'" class="mt-6">
|
||||
<x-input-label for="bot_token" :value="__('Bot Token')" />
|
||||
<x-text-input
|
||||
value="{{ old('bot_token') }}"
|
||||
id="bot_token"
|
||||
name="bot_token"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("bot_token")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="provider === 'telegram'" class="mt-6">
|
||||
<x-input-label for="chat_id" :value="__('Chat ID')" />
|
||||
<x-text-input
|
||||
value="{{ old('chat_id') }}"
|
||||
id="chat_id"
|
||||
name="chat_id"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("chat_id")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-add-channel" class="ml-3">
|
||||
{{ __("Add") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
||||
</div>
|
@ -0,0 +1,45 @@
|
||||
<div>
|
||||
<x-card-header>
|
||||
<x-slot name="title">{{ __("Notification Channels") }}</x-slot>
|
||||
<x-slot name="description">
|
||||
{{ __("Add or modify your notification channels") }}
|
||||
</x-slot>
|
||||
<x-slot name="aside">
|
||||
@include("settings.notification-channels.partials.add-channel")
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<div x-data="{ deleteAction: '' }" class="space-y-3">
|
||||
@if (count($channels) > 0)
|
||||
@foreach ($channels as $channel)
|
||||
<x-item-card>
|
||||
<div class="flex-none text-gray-600 dark:text-gray-300">
|
||||
@include("settings.notification-channels.partials.icons." . $channel->provider)
|
||||
</div>
|
||||
<div class="ml-3 flex flex-grow flex-col items-start justify-center">
|
||||
<span class="mb-1">{{ $channel->label }}</span>
|
||||
<span class="text-sm text-gray-400">
|
||||
<x-datetime :value="$channel->created_at" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="inline">
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('notification-channels.delete', $channel->id) }}'; $dispatch('open-modal', 'delete-channel')"
|
||||
>
|
||||
<x-heroicon name="o-trash" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</x-item-card>
|
||||
@endforeach
|
||||
|
||||
@include("settings.notification-channels.partials.delete-channel")
|
||||
@else
|
||||
<x-simple-card>
|
||||
<div class="text-center">
|
||||
{{ __("You haven't connected to any channels yet!") }}
|
||||
</div>
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,18 @@
|
||||
<x-modal name="delete-channel" :show="$errors->isNotEmpty()">
|
||||
<form id="delete-channel-form" method="post" x-bind:action="deleteAction" class="p-6">
|
||||
@csrf
|
||||
@method("delete")
|
||||
|
||||
<h2 class="text-lg font-medium">Are you sure that you want to delete this channel?</h2>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-danger-button class="ml-3">
|
||||
{{ __("Delete") }}
|
||||
</x-danger-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,16 @@
|
||||
<svg
|
||||
class="h-10 w-10"
|
||||
viewBox="0 -28.5 256 256"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
preserveAspectRatio="xMidYMid"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M216.856339,16.5966031 C200.285002,8.84328665 182.566144,3.2084988 164.041564,0 C161.766523,4.11318106 159.108624,9.64549908 157.276099,14.0464379 C137.583995,11.0849896 118.072967,11.0849896 98.7430163,14.0464379 C96.9108417,9.64549908 94.1925838,4.11318106 91.8971895,0 C73.3526068,3.2084988 55.6133949,8.86399117 39.0420583,16.6376612 C5.61752293,67.146514 -3.4433191,116.400813 1.08711069,164.955721 C23.2560196,181.510915 44.7403634,191.567697 65.8621325,198.148576 C71.0772151,190.971126 75.7283628,183.341335 79.7352139,175.300261 C72.104019,172.400575 64.7949724,168.822202 57.8887866,164.667963 C59.7209612,163.310589 61.5131304,161.891452 63.2445898,160.431257 C105.36741,180.133187 151.134928,180.133187 192.754523,160.431257 C194.506336,161.891452 196.298154,163.310589 198.110326,164.667963 C191.183787,168.842556 183.854737,172.420929 176.223542,175.320965 C180.230393,183.341335 184.861538,190.991831 190.096624,198.16893 C211.238746,191.588051 232.743023,181.531619 254.911949,164.955721 C260.227747,108.668201 245.831087,59.8662432 216.856339,16.5966031 Z M85.4738752,135.09489 C72.8290281,135.09489 62.4592217,123.290155 62.4592217,108.914901 C62.4592217,94.5396472 72.607595,82.7145587 85.4738752,82.7145587 C98.3405064,82.7145587 108.709962,94.5189427 108.488529,108.914901 C108.508531,123.290155 98.3405064,135.09489 85.4738752,135.09489 Z M170.525237,135.09489 C157.88039,135.09489 147.510584,123.290155 147.510584,108.914901 C147.510584,94.5396472 157.658606,82.7145587 170.525237,82.7145587 C183.391518,82.7145587 193.761324,94.5189427 193.539891,108.914901 C193.539891,123.290155 183.391518,135.09489 170.525237,135.09489 Z"
|
||||
fill="#5865F2"
|
||||
fill-rule="nonzero"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1 @@
|
||||
<x-heroicon name="o-envelope" class="h-10 w-10" />
|
@ -0,0 +1,18 @@
|
||||
<svg class="h-10 w-10" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M26.5002 14.9996C27.8808 14.9996 29 13.8804 29 12.4998C29 11.1192 27.8807 10 26.5001 10C25.1194 10 24 11.1193 24 12.5V14.9996H26.5002ZM19.5 14.9996C20.8807 14.9996 22 13.8803 22 12.4996V5.5C22 4.11929 20.8807 3 19.5 3C18.1193 3 17 4.11929 17 5.5V12.4996C17 13.8803 18.1193 14.9996 19.5 14.9996Z"
|
||||
fill="#2EB67D"
|
||||
/>
|
||||
<path
|
||||
d="M5.49979 17.0004C4.11919 17.0004 3 18.1196 3 19.5002C3 20.8808 4.1193 22 5.49989 22C6.8806 22 8 20.8807 8 19.5V17.0004H5.49979ZM12.5 17.0004C11.1193 17.0004 10 18.1197 10 19.5004V26.5C10 27.8807 11.1193 29 12.5 29C13.8807 29 15 27.8807 15 26.5V19.5004C15 18.1197 13.8807 17.0004 12.5 17.0004Z"
|
||||
fill="#E01E5A"
|
||||
/>
|
||||
<path
|
||||
d="M17.0004 26.5002C17.0004 27.8808 18.1196 29 19.5002 29C20.8808 29 22 27.8807 22 26.5001C22 25.1194 20.8807 24 19.5 24L17.0004 24L17.0004 26.5002ZM17.0004 19.5C17.0004 20.8807 18.1197 22 19.5004 22L26.5 22C27.8807 22 29 20.8807 29 19.5C29 18.1193 27.8807 17 26.5 17L19.5004 17C18.1197 17 17.0004 18.1193 17.0004 19.5Z"
|
||||
fill="#ECB22E"
|
||||
/>
|
||||
<path
|
||||
d="M14.9996 5.49979C14.9996 4.11919 13.8804 3 12.4998 3C11.1192 3 10 4.1193 10 5.49989C10 6.88061 11.1193 8 12.5 8L14.9996 8L14.9996 5.49979ZM14.9996 12.5C14.9996 11.1193 13.8803 10 12.4996 10L5.5 10C4.11929 10 3 11.1193 3 12.5C3 13.8807 4.11929 15 5.5 15L12.4996 15C13.8803 15 14.9996 13.8807 14.9996 12.5Z"
|
||||
fill="#36C5F0"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,27 @@
|
||||
<svg
|
||||
class="h-10 w-10"
|
||||
viewBox="0 0 256 256"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
preserveAspectRatio="xMidYMid"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M128,0 C57.307,0 0,57.307 0,128 L0,128 C0,198.693 57.307,256 128,256 L128,256 C198.693,256 256,198.693 256,128 L256,128 C256,57.307 198.693,0 128,0 L128,0 Z"
|
||||
fill="#40B3E0"
|
||||
></path>
|
||||
<path
|
||||
d="M190.2826,73.6308 L167.4206,188.8978 C167.4206,188.8978 164.2236,196.8918 155.4306,193.0548 L102.6726,152.6068 L83.4886,143.3348 L51.1946,132.4628 C51.1946,132.4628 46.2386,130.7048 45.7586,126.8678 C45.2796,123.0308 51.3546,120.9528 51.3546,120.9528 L179.7306,70.5928 C179.7306,70.5928 190.2826,65.9568 190.2826,73.6308"
|
||||
fill="#FFFFFF"
|
||||
></path>
|
||||
<path
|
||||
d="M98.6178,187.6035 C98.6178,187.6035 97.0778,187.4595 95.1588,181.3835 C93.2408,175.3085 83.4888,143.3345 83.4888,143.3345 L161.0258,94.0945 C161.0258,94.0945 165.5028,91.3765 165.3428,94.0945 C165.3428,94.0945 166.1418,94.5735 163.7438,96.8115 C161.3458,99.0505 102.8328,151.6475 102.8328,151.6475"
|
||||
fill="#D2E5F1"
|
||||
></path>
|
||||
<path
|
||||
d="M122.9015,168.1154 L102.0335,187.1414 C102.0335,187.1414 100.4025,188.3794 98.6175,187.6034 L102.6135,152.2624"
|
||||
fill="#B5CFE4"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
9
resources/views/settings/profile/index.blade.php
Normal file
9
resources/views/settings/profile/index.blade.php
Normal file
@ -0,0 +1,9 @@
|
||||
<x-profile-layout>
|
||||
<x-slot name="pageTitle">{{ __("Profile") }}</x-slot>
|
||||
|
||||
@include("settings.profile.partials.update-profile-information")
|
||||
|
||||
@include("settings.profile.partials.update-password")
|
||||
|
||||
@include("settings.profile.partials.two-factor-authentication")
|
||||
</x-profile-layout>
|
@ -0,0 +1,60 @@
|
||||
<x-card>
|
||||
<x-slot name="title">
|
||||
{{ __("Two Factor Authentication") }}
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="description">
|
||||
{{ __("Here you can activate 2FA to secure your account") }}
|
||||
</x-slot>
|
||||
|
||||
@if (! auth()->user()->two_factor_secret)
|
||||
{{-- Enable 2FA --}}
|
||||
<form method="POST" action="{{ route("two-factor.enable") }}">
|
||||
@csrf
|
||||
|
||||
<x-primary-button type="submit">
|
||||
{{ __("Enable Two-Factor") }}
|
||||
</x-primary-button>
|
||||
</form>
|
||||
@else
|
||||
{{-- Disable 2FA --}}
|
||||
<form method="POST" action="{{ route("two-factor.disable") }}">
|
||||
@csrf
|
||||
@method("DELETE")
|
||||
|
||||
<x-danger-button type="submit">
|
||||
{{ __("Disable Two-Factor") }}
|
||||
</x-danger-button>
|
||||
</form>
|
||||
|
||||
@if (session("status") == "two-factor-authentication-enabled")
|
||||
<div class="mt-5">
|
||||
{{ __('Two factor authentication is now enabled. Scan the following QR code using your phone\'s authenticator application.') }}
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
{!! auth()->user()->twoFactorQrCodeSvg() !!}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Show 2FA Recovery Codes --}}
|
||||
<div class="mt-5">
|
||||
{{ __("Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.") }}
|
||||
</div>
|
||||
|
||||
<div class="mt-5 rounded-md border border-gray-100 p-2 dark:border-gray-700">
|
||||
@foreach (json_decode(decrypt(auth()->user()->two_factor_recovery_codes), true) as $code)
|
||||
<div class="mt-2">{{ $code }}</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
{{-- Regenerate 2FA Recovery Codes --}}
|
||||
<form class="mt-5" method="POST" action="{{ route("two-factor.recovery-codes") }}">
|
||||
@csrf
|
||||
|
||||
<x-primary-button type="submit">
|
||||
{{ __("Regenerate Recovery Codes") }}
|
||||
</x-primary-button>
|
||||
</form>
|
||||
@endif
|
||||
</x-card>
|
@ -0,0 +1,69 @@
|
||||
<x-card>
|
||||
<x-slot name="title">
|
||||
{{ __("Update Password") }}
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="description">
|
||||
{{ __("Ensure your account is using a long, random password to stay secure.") }}
|
||||
</x-slot>
|
||||
|
||||
<form
|
||||
id="update-password"
|
||||
class="mt-6 space-y-6"
|
||||
hx-post="{{ route("profile.password") }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#update-password"
|
||||
hx-trigger="submit"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-save-password"
|
||||
>
|
||||
@csrf
|
||||
|
||||
<div>
|
||||
<x-input-label for="current_password" :value="__('Current Password')" />
|
||||
<x-text-input
|
||||
id="current_password"
|
||||
name="current_password"
|
||||
type="password"
|
||||
class="mt-1 block w-full"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
@error("current_password")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<x-input-label for="password" :value="__('New Password')" />
|
||||
<x-text-input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
class="mt-1 block w-full"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
@error("password")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<x-input-label for="password_confirmation" :value="__('Confirm Password')" />
|
||||
<x-text-input
|
||||
id="password_confirmation"
|
||||
name="password_confirmation"
|
||||
type="password"
|
||||
class="mt-1 block w-full"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
@error("password_confirmation")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</form>
|
||||
<x-slot name="actions">
|
||||
<x-primary-button id="btn-save-password" form="update-password">
|
||||
{{ __("Save") }}
|
||||
</x-primary-button>
|
||||
</x-slot>
|
||||
</x-card>
|
@ -0,0 +1,80 @@
|
||||
@php
|
||||
$user = auth()->user();
|
||||
@endphp
|
||||
|
||||
<x-card>
|
||||
<x-slot name="title">
|
||||
{{ __("Profile Information") }}
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="description">
|
||||
{{ __("Update your account's profile information and email address.") }}
|
||||
</x-slot>
|
||||
|
||||
<form
|
||||
id="update-profile-information"
|
||||
hx-post="{{ route("profile.info") }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#update-profile-information"
|
||||
hx-trigger="submit"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-save-info"
|
||||
class="mt-6 space-y-6"
|
||||
>
|
||||
@csrf
|
||||
<div>
|
||||
<x-input-label for="name" :value="__('Name')" />
|
||||
<x-text-input
|
||||
id="name"
|
||||
name="name"
|
||||
type="text"
|
||||
value="{{ old('name', auth()->user()->name) }}"
|
||||
class="mt-1 block w-full"
|
||||
required
|
||||
autocomplete="name"
|
||||
/>
|
||||
@error("name")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<x-input-label for="email" :value="__('Email')" />
|
||||
<x-text-input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
value="{{ old('email', auth()->user()->email) }}"
|
||||
class="mt-1 block w-full"
|
||||
required
|
||||
autocomplete="email"
|
||||
/>
|
||||
@error("email")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<x-input-label for="timezone" :value="__('Timezone')" />
|
||||
<x-select-input id="timezone" name="timezone" class="mt-1 block w-full" required>
|
||||
@foreach (timezone_identifiers_list() as $timezone)
|
||||
<option
|
||||
value="{{ $timezone }}"
|
||||
@if(old('timezone', auth()->user()->timezone) == $timezone) selected @endif
|
||||
>
|
||||
{{ $timezone }}
|
||||
</option>
|
||||
@endforeach
|
||||
</x-select-input>
|
||||
@error("timezone")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<x-slot name="actions">
|
||||
<x-primary-button id="btn-save-info" form="update-profile-information">
|
||||
{{ __("Save") }}
|
||||
</x-primary-button>
|
||||
</x-slot>
|
||||
</x-card>
|
5
resources/views/settings/projects/index.blade.php
Normal file
5
resources/views/settings/projects/index.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
<x-profile-layout>
|
||||
<x-slot name="pageTitle">{{ __("Projects") }}</x-slot>
|
||||
|
||||
@include("settings.projects.partials.projects-list")
|
||||
</x-profile-layout>
|
@ -0,0 +1,40 @@
|
||||
<div>
|
||||
<x-primary-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'create-project')">
|
||||
{{ __("Create") }}
|
||||
</x-primary-button>
|
||||
|
||||
<x-modal name="create-project" :show="request()->has('create')">
|
||||
<form
|
||||
id="create-project-form"
|
||||
hx-post="{{ route("projects.create") }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#create-project-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-create-project"
|
||||
class="p-6"
|
||||
>
|
||||
@csrf
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Create Project") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="name" value="Name" />
|
||||
<x-text-input value="{{ old('name') }}" id="name" name="name" type="text" class="mt-1 w-full" />
|
||||
@error("name")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-create-project" class="ml-3">
|
||||
{{ __("Create") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
||||
</div>
|
@ -0,0 +1,20 @@
|
||||
<x-modal name="delete-project" :show="$errors->isNotEmpty()">
|
||||
<form id="delete-project-form" method="post" x-bind:action="deleteAction" class="p-6">
|
||||
@csrf
|
||||
@method("delete")
|
||||
|
||||
<h2 class="text-lg font-medium">
|
||||
Deleting a project will delete all of its servers, sites, etc. Are you sure you want to delete this project?
|
||||
</h2>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-danger-button class="ml-3">
|
||||
{{ __("Delete") }}
|
||||
</x-danger-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,47 @@
|
||||
<div>
|
||||
<x-icon-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'edit-project-{{ $project->id }}')">
|
||||
<x-heroicon name="o-pencil" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
|
||||
<x-modal name="edit-project-{{ $project->id }}">
|
||||
<form
|
||||
id="edit-project-form-{{ $project->id }}"
|
||||
hx-post="{{ route("projects.update", $project) }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#edit-project-form-{{ $project->id }}"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-edit-project-{{ $project->id }}"
|
||||
class="p-6 text-left"
|
||||
>
|
||||
@csrf
|
||||
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Edit Project") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="edit-name-{{ $project->id }}" value="Name" />
|
||||
<x-text-input
|
||||
value="{{ old('name', $project->name) }}"
|
||||
id="edit-name-{{ $project->id }}"
|
||||
name="name"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("name")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-edit-project-{{ $project->id }}" class="ml-3">
|
||||
{{ __("Save") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
||||
</div>
|
@ -0,0 +1,40 @@
|
||||
<div>
|
||||
<x-card-header>
|
||||
<x-slot name="title">{{ __("Projects") }}</x-slot>
|
||||
<x-slot name="description">
|
||||
{{ __("Here you can manage your projects") }}
|
||||
</x-slot>
|
||||
<x-slot name="aside">
|
||||
@include("settings.projects.partials.create-project")
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<div id="projects-list" x-data="{ deleteAction: '' }" class="space-y-3">
|
||||
@foreach ($projects as $project)
|
||||
<x-item-card>
|
||||
<div class="ml-3 flex flex-grow flex-col items-start justify-center">
|
||||
<div class="mb-1 flex items-center">
|
||||
{{ $project->name }}
|
||||
@if ($project->id == auth()->user()->current_project_id)
|
||||
<x-status status="success" class="ml-1">
|
||||
{{ __("Current") }}
|
||||
</x-status>
|
||||
@endif
|
||||
</div>
|
||||
<span class="text-sm text-gray-400">
|
||||
<x-datetime :value="$project->created_at" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
@include("settings.projects.partials.edit-project", ["project" => $project])
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('projects.delete', $project) }}'; $dispatch('open-modal', 'delete-project')"
|
||||
>
|
||||
<x-heroicon name="o-trash" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</div>
|
||||
</x-item-card>
|
||||
@endforeach
|
||||
|
||||
@include("settings.projects.partials.delete-project")
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,5 @@
|
||||
<x-profile-layout>
|
||||
<x-slot name="pageTitle">{{ __("Storage Providers") }}</x-slot>
|
||||
|
||||
@include("settings.server-providers.partials.providers-list")
|
||||
</x-profile-layout>
|
@ -0,0 +1,97 @@
|
||||
<div>
|
||||
<x-primary-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'connect-provider')">
|
||||
{{ __("Connect") }}
|
||||
</x-primary-button>
|
||||
|
||||
<x-modal name="connect-provider" :show="request()->has('provider')">
|
||||
@php
|
||||
$oldProvider = old("provider", request()->input("provider") ?? "");
|
||||
@endphp
|
||||
|
||||
<form
|
||||
id="connect-provider-form"
|
||||
hx-post="{{ route("server-providers.connect") }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#connect-provider-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-connect-provider"
|
||||
class="p-6"
|
||||
x-data="{ provider: '{{ $oldProvider }}' }"
|
||||
>
|
||||
@csrf
|
||||
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Connect to a Server Provider") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="provider" value="Provider" />
|
||||
<x-select-input x-model="provider" id="provider" name="provider" class="mt-1 w-full">
|
||||
<option value="" selected disabled>
|
||||
{{ __("Select") }}
|
||||
</option>
|
||||
@foreach (config("core.server_providers") as $p)
|
||||
@if ($p !== "custom")
|
||||
<option value="{{ $p }}" @if($oldProvider === $p) selected @endif>
|
||||
{{ $p }}
|
||||
</option>
|
||||
@endif
|
||||
@endforeach
|
||||
</x-select-input>
|
||||
@error("provider")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="name" value="Name" />
|
||||
<x-text-input value="{{ old('name') }}" id="name" name="name" type="text" class="mt-1 w-full" />
|
||||
@error("name")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="provider === 'aws'">
|
||||
<div class="mt-6">
|
||||
<x-input-label for="key" value="Access Key" />
|
||||
<x-text-input value="{{ old('key') }}" id="key" name="key" type="text" class="mt-1 w-full" />
|
||||
@error("key")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="secret" value="Secret" />
|
||||
<x-text-input
|
||||
value="{{ old('secret') }}"
|
||||
id="secret"
|
||||
name="secret"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("secret")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-show="['hetzner', 'digitalocean', 'vultr', 'linode'].includes(provider)" class="mt-6">
|
||||
<x-input-label for="token" value="API Key" />
|
||||
<x-text-input value="{{ old('token') }}" id="token" name="token" type="text" class="mt-1 w-full" />
|
||||
@error("token")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-connect-provider" class="ml-3">
|
||||
{{ __("Connect") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
||||
</div>
|
@ -0,0 +1,18 @@
|
||||
<x-modal name="delete-provider" :show="$errors->isNotEmpty()">
|
||||
<form id="delete-provider-form" method="post" x-bind:action="deleteAction" class="p-6">
|
||||
@csrf
|
||||
@method("delete")
|
||||
|
||||
<h2 class="text-lg font-medium">Are you sure that you want to delete this provider?</h2>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-danger-button class="ml-3">
|
||||
{{ __("Delete") }}
|
||||
</x-danger-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,47 @@
|
||||
<div>
|
||||
<x-card-header>
|
||||
<x-slot name="title">Server Providers</x-slot>
|
||||
<x-slot name="description">You can connect to your server providers to create servers using their APIs</x-slot>
|
||||
<x-slot name="aside">
|
||||
@include("settings.server-providers.partials.connect-provider")
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<div x-data="{ deleteAction: '' }" class="space-y-3">
|
||||
@if (count($providers) > 0)
|
||||
@foreach ($providers as $provider)
|
||||
<x-item-card>
|
||||
<div class="flex-none">
|
||||
<img
|
||||
src="{{ asset("static/images/" . $provider->provider . ".svg") }}"
|
||||
class="h-10 w-10"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div class="ml-3 flex flex-grow flex-col items-start justify-center">
|
||||
<span class="mb-1">{{ $provider->profile }}</span>
|
||||
<span class="text-sm text-gray-400">
|
||||
<x-datetime :value="$provider->created_at" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="inline">
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('server-providers.delete', $provider->id) }}'; $dispatch('open-modal', 'delete-provider')"
|
||||
>
|
||||
<x-heroicon name="o-trash" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</x-item-card>
|
||||
@endforeach
|
||||
|
||||
@include("settings.server-providers.partials.delete-provider")
|
||||
@else
|
||||
<x-simple-card>
|
||||
<div class="text-center">
|
||||
{{ __("You haven't connected to any server providers yet!") }}
|
||||
</div>
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
5
resources/views/settings/source-controls/index.blade.php
Normal file
5
resources/views/settings/source-controls/index.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
<x-profile-layout>
|
||||
<x-slot name="pageTitle">{{ __("Source Controls") }}</x-slot>
|
||||
|
||||
@include("settings.source-controls.partials.source-controls-list")
|
||||
</x-profile-layout>
|
@ -0,0 +1,134 @@
|
||||
<div>
|
||||
<x-primary-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'connect-source-control')">
|
||||
{{ __("Connect") }}
|
||||
</x-primary-button>
|
||||
|
||||
<x-modal name="connect-source-control" :show="request()->has('provider')">
|
||||
@php
|
||||
$oldProvider = old("provider", request()->input("provider") ?? "");
|
||||
@endphp
|
||||
|
||||
<form
|
||||
id="connect-source-control-form"
|
||||
hx-post="{{ route("source-controls.connect") }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#connect-source-control-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-connect-source-control"
|
||||
class="p-6"
|
||||
x-data="{ provider: '{{ $oldProvider }}' }"
|
||||
>
|
||||
@csrf
|
||||
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Connect to a Source Control") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="provider" value="Provider" />
|
||||
<x-select-input x-model="provider" id="provider" name="provider" class="mt-1 w-full">
|
||||
<option value="" selected disabled>
|
||||
{{ __("Select") }}
|
||||
</option>
|
||||
@foreach (config("core.source_control_providers") as $p)
|
||||
@if ($p !== "custom")
|
||||
<option value="{{ $p }}" @if($oldProvider === $p) selected @endif>
|
||||
{{ $p }}
|
||||
</option>
|
||||
@endif
|
||||
@endforeach
|
||||
</x-select-input>
|
||||
@error("provider")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="name" value="Name" />
|
||||
<x-text-input value="{{ old('name') }}" id="name" name="name" type="text" class="mt-1 w-full" />
|
||||
@error("name")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="provider === 'gitlab'" class="mt-6">
|
||||
<x-input-label for="url" value="Url (optional)" />
|
||||
<x-text-input
|
||||
value="{{ old('url') }}"
|
||||
id="url"
|
||||
name="url"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
placeholder="e.g. https://gitlab.example.com/"
|
||||
/>
|
||||
<x-input-help>
|
||||
If you run a self-managed gitlab enter the url here, leave empty to use gitlab.com
|
||||
</x-input-help>
|
||||
@error("url")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="['gitlab', 'github'].includes(provider)" class="mt-6">
|
||||
<x-input-label for="token" value="API Key" />
|
||||
<x-text-input value="{{ old('token') }}" id="token" name="token" type="text" class="mt-1 w-full" />
|
||||
@error("token")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="provider === 'bitbucket'">
|
||||
<div class="mt-6">
|
||||
<x-input-label for="username" value="Username" />
|
||||
<x-text-input
|
||||
value="{{ old('username') }}"
|
||||
id="username"
|
||||
name="username"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
<x-input-help>Your Bitbucket username</x-input-help>
|
||||
@error("username")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="password" value="Password" />
|
||||
<x-text-input
|
||||
value="{{ old('password') }}"
|
||||
id="password"
|
||||
name="password"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
<x-input-help>
|
||||
Create a new
|
||||
<a
|
||||
class="text-primary-500"
|
||||
href="https://bitbucket.org/account/settings/app-passwords/new"
|
||||
target="_blank"
|
||||
>
|
||||
App Password
|
||||
</a>
|
||||
in your Bitbucket account with write and admin access to Workspaces, Projects, Repositories and
|
||||
Webhooks
|
||||
</x-input-help>
|
||||
@error("password")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-connect-source-control" class="ml-3">
|
||||
{{ __("Connect") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
||||
</div>
|
@ -0,0 +1,18 @@
|
||||
<x-modal name="delete-source-control" :show="$errors->isNotEmpty()">
|
||||
<form id="delete-source-control-form" method="post" x-bind:action="deleteAction" class="p-6">
|
||||
@csrf
|
||||
@method("delete")
|
||||
|
||||
<h2 class="text-lg font-medium">Are you sure that you want to delete this source control?</h2>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-danger-button class="ml-3">
|
||||
{{ __("Delete") }}
|
||||
</x-danger-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,25 @@
|
||||
<svg class="h-10 w-10" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M2.9087 3.00008C2.64368 2.99655 2.3907 3.11422 2.21764 3.32152C2.04458 3.52883 1.96915 3.80455 2.01158 4.07472L5.81987 27.9484C5.91782 28.5515 6.42093 28.9949 7.01305 28.9999H25.283C25.7274 29.0058 26.109 28.6748 26.1801 28.2217L29.9884 4.07935C30.0309 3.80918 29.9554 3.53346 29.7824 3.32615C29.6093 3.11885 29.3563 3.00118 29.0913 3.00471L2.9087 3.00008ZM18.9448 20.2546H13.1135L11.5346 11.7362H20.3578L18.9448 20.2546Z"
|
||||
fill="#2684FF"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M28.7778 11.7363H20.3582L18.9453 20.2547H13.114L6.22852 28.6944C6.44675 28.8892 6.725 28.9976 7.0135 29.0001H25.2879C25.7324 29.006 26.114 28.675 26.1851 28.2219L28.7778 11.7363Z"
|
||||
fill="url(#paint0_linear_87_7932)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_87_7932"
|
||||
x1="30.7245"
|
||||
y1="14.1218"
|
||||
x2="20.5764"
|
||||
y2="28.0753"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.18" stop-color="#0052CC" />
|
||||
<stop offset="1" stop-color="#2684FF" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,19 @@
|
||||
<svg
|
||||
class="h-10 w-10"
|
||||
viewBox="0 -0.5 48 48"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<title>Github-color</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Color-" transform="translate(-700.000000, -560.000000)" fill="#3E75C3">
|
||||
<path
|
||||
d="M723.9985,560 C710.746,560 700,570.787092 700,584.096644 C700,594.740671 706.876,603.77183 716.4145,606.958412 C717.6145,607.179786 718.0525,606.435849 718.0525,605.797328 C718.0525,605.225068 718.0315,603.710086 718.0195,601.699648 C711.343,603.155898 709.9345,598.469394 709.9345,598.469394 C708.844,595.686405 707.2705,594.94548 707.2705,594.94548 C705.091,593.450075 707.4355,593.480194 707.4355,593.480194 C709.843,593.650366 711.1105,595.963499 711.1105,595.963499 C713.2525,599.645538 716.728,598.58234 718.096,597.964902 C718.3135,596.407754 718.9345,595.346062 719.62,594.743683 C714.2905,594.135281 708.688,592.069123 708.688,582.836167 C708.688,580.205279 709.6225,578.054788 711.1585,576.369634 C710.911,575.759726 710.0875,573.311058 711.3925,569.993458 C711.3925,569.993458 713.4085,569.345902 717.9925,572.46321 C719.908,571.928599 721.96,571.662047 724.0015,571.651505 C726.04,571.662047 728.0935,571.928599 730.0105,572.46321 C734.5915,569.345902 736.603,569.993458 736.603,569.993458 C737.9125,573.311058 737.089,575.759726 736.8415,576.369634 C738.3805,578.054788 739.309,580.205279 739.309,582.836167 C739.309,592.091712 733.6975,594.129257 728.3515,594.725612 C729.2125,595.469549 729.9805,596.939353 729.9805,599.18773 C729.9805,602.408949 729.9505,605.006706 729.9505,605.797328 C729.9505,606.441873 730.3825,607.191834 731.6005,606.9554 C741.13,603.762794 748,594.737659 748,584.096644 C748,570.787092 737.254,560 723.9985,560"
|
||||
id="Github"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1,13 @@
|
||||
<svg class="h-10 w-10" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none">
|
||||
<path
|
||||
fill="#FC6D26"
|
||||
d="M14.975 8.904L14.19 6.55l-1.552-4.67a.268.268 0 00-.255-.18.268.268 0 00-.254.18l-1.552 4.667H5.422L3.87 1.879a.267.267 0 00-.254-.179.267.267 0 00-.254.18l-1.55 4.667-.784 2.357a.515.515 0 00.193.583l6.78 4.812 6.778-4.812a.516.516 0 00.196-.583z"
|
||||
/>
|
||||
<path fill="#E24329" d="M8 14.296l2.578-7.75H5.423L8 14.296z" />
|
||||
<path fill="#FC6D26" d="M8 14.296l-2.579-7.75H1.813L8 14.296z" />
|
||||
<path fill="#FCA326" d="M1.81 6.549l-.784 2.354a.515.515 0 00.193.583L8 14.3 1.81 6.55z" />
|
||||
<path fill="#E24329" d="M1.812 6.549h3.612L3.87 1.882a.268.268 0 00-.254-.18.268.268 0 00-.255.18L1.812 6.549z" />
|
||||
<path fill="#FC6D26" d="M8 14.296l2.578-7.75h3.614L8 14.296z" />
|
||||
<path fill="#FCA326" d="M14.19 6.549l.783 2.354a.514.514 0 01-.193.583L8 14.296l6.188-7.747h.001z" />
|
||||
<path fill="#E24329" d="M14.19 6.549H10.58l1.551-4.667a.267.267 0 01.255-.18c.115 0 .217.073.254.18l1.552 4.667z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,43 @@
|
||||
<div>
|
||||
<x-card-header>
|
||||
<x-slot name="title">Source Controls</x-slot>
|
||||
<x-slot name="description">You can connect your source controls via API Tokens</x-slot>
|
||||
<x-slot name="aside">
|
||||
@include("settings.source-controls.partials.connect")
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<div x-data="{ deleteAction: '' }" class="space-y-3">
|
||||
@if (count($sourceControls) > 0)
|
||||
@foreach ($sourceControls as $sourceControl)
|
||||
<x-item-card>
|
||||
<div class="flex-none text-gray-600 dark:text-gray-300">
|
||||
@include("settings.source-controls.partials.icons." . $sourceControl->provider . "-icon")
|
||||
</div>
|
||||
<div class="ml-3 flex flex-grow flex-col items-start justify-center">
|
||||
<span class="mb-1">{{ $sourceControl->profile }}</span>
|
||||
<span class="text-sm text-gray-400">
|
||||
<x-datetime :value="$sourceControl->created_at" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="inline">
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('source-controls.delete', $sourceControl->id) }}'; $dispatch('open-modal', 'delete-source-control')"
|
||||
>
|
||||
<x-heroicon name="o-trash" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</x-item-card>
|
||||
@endforeach
|
||||
|
||||
@include("settings.source-controls.partials.delete-source-control")
|
||||
@else
|
||||
<x-simple-card>
|
||||
<div class="text-center">
|
||||
{{ __("You haven't connected to any server source controls yet!") }}
|
||||
</div>
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
5
resources/views/settings/ssh-keys/index.blade.php
Normal file
5
resources/views/settings/ssh-keys/index.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
<x-profile-layout>
|
||||
<x-slot name="pageTitle">{{ __("SSH Keys") }}</x-slot>
|
||||
|
||||
@include("settings.ssh-keys.partials.keys-list")
|
||||
</x-profile-layout>
|
50
resources/views/settings/ssh-keys/partials/add-key.blade.php
Normal file
50
resources/views/settings/ssh-keys/partials/add-key.blade.php
Normal file
@ -0,0 +1,50 @@
|
||||
<div>
|
||||
<x-primary-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'add-key')">
|
||||
{{ __("Add new Key") }}
|
||||
</x-primary-button>
|
||||
|
||||
<x-modal name="add-key">
|
||||
<form
|
||||
id="add-ssh-key-form"
|
||||
hx-post="{{ route("ssh-keys.add") }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#add-ssh-key-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-add-key"
|
||||
class="p-6"
|
||||
>
|
||||
@csrf
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Add new Key") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="name" :value="__('Name')" />
|
||||
<x-text-input value="{{ old('name') }}" id="name" name="name" type="text" class="mt-1 w-full" />
|
||||
@error("name")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="public_key" :value="__('Public Key')" />
|
||||
<x-textarea id="public_key" name="public_key" class="mt-1 w-full" rows="5">
|
||||
{{ old("public_key") }}
|
||||
</x-textarea>
|
||||
@error("public_key")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-add-key" class="ml-3">
|
||||
{{ __("Add") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
||||
</div>
|
@ -0,0 +1,18 @@
|
||||
<x-modal name="delete-ssh-key" :show="$errors->isNotEmpty()">
|
||||
<form id="delete-ssh-key-form" method="post" x-bind:action="deleteAction" class="p-6">
|
||||
@csrf
|
||||
@method("delete")
|
||||
|
||||
<h2 class="text-lg font-medium">Are you sure that you want to delete this key?</h2>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-danger-button class="ml-3">
|
||||
{{ __("Delete") }}
|
||||
</x-danger-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,42 @@
|
||||
<div>
|
||||
<x-card-header>
|
||||
<x-slot name="title">{{ __("SSH Keys") }}</x-slot>
|
||||
<x-slot name="description">
|
||||
{{ __("Add or modify your ssh keys") }}
|
||||
</x-slot>
|
||||
<x-slot name="aside">
|
||||
@include("settings.ssh-keys.partials.add-key")
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<div x-data="{ deleteAction: '' }" class="space-y-3">
|
||||
@if (count($keys) > 0)
|
||||
@foreach ($keys as $key)
|
||||
<x-item-card>
|
||||
<div class="flex flex-grow flex-col items-start justify-center">
|
||||
<span class="mb-1">{{ $key->name }}</span>
|
||||
<span class="text-sm text-gray-400">
|
||||
<x-datetime :value="$key->created_at" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="inline">
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('ssh-keys.delete', $key->id) }}'; $dispatch('open-modal', 'delete-ssh-key')"
|
||||
>
|
||||
<x-heroicon name="o-trash" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</x-item-card>
|
||||
@endforeach
|
||||
|
||||
@include("settings.ssh-keys.partials.delete-ssh-key")
|
||||
@else
|
||||
<x-simple-card>
|
||||
<div class="text-center">
|
||||
{{ __("You haven't connected to any keys yet!") }}
|
||||
</div>
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,5 @@
|
||||
<x-profile-layout>
|
||||
<x-slot name="pageTitle">{{ __("Storage Providers") }}</x-slot>
|
||||
|
||||
@include("settings.storage-providers.partials.providers-list")
|
||||
</x-profile-layout>
|
@ -0,0 +1,167 @@
|
||||
<div>
|
||||
<x-primary-button x-data="" x-on:click.prevent="$dispatch('open-modal', 'connect-provider')">
|
||||
{{ __("Connect") }}
|
||||
</x-primary-button>
|
||||
|
||||
<x-modal name="connect-provider">
|
||||
@php
|
||||
$oldProvider = old("provider", request()->input("provider") ?? "dropbox");
|
||||
@endphp
|
||||
|
||||
<form
|
||||
id="connect-storage-provider-form"
|
||||
hx-post="{{ route("storage-providers.connect") }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-select="#connect-storage-provider-form"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#btn-connect-storage-provider"
|
||||
class="p-6"
|
||||
x-data="{ provider: '{{ $oldProvider }}' }"
|
||||
>
|
||||
@csrf
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __("Connect to a Storage Provider") }}
|
||||
</h2>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="provider" value="Provider" />
|
||||
<x-select-input x-model="provider" id="provider" name="provider" class="mt-1 w-full">
|
||||
<option value="" selected disabled>
|
||||
{{ __("Select") }}
|
||||
</option>
|
||||
@foreach (config("core.storage_providers") as $p)
|
||||
@if ($p !== "custom")
|
||||
<option value="{{ $p }}" @if($oldProvider === $p) selected @endif>
|
||||
{{ $p }}
|
||||
@if ($p === "ftp")
|
||||
(Beta)
|
||||
@endif
|
||||
</option>
|
||||
@endif
|
||||
@endforeach
|
||||
</x-select-input>
|
||||
@error("provider")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<x-input-label for="name" value="Name" />
|
||||
<x-text-input value="{{ old('name') }}" id="name" name="name" type="text" class="mt-1 w-full" />
|
||||
@error("name")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div x-show="provider === 'dropbox'" class="mt-6">
|
||||
<x-input-label for="token" value="API Key" />
|
||||
<x-text-input value="{{ old('token') }}" id="token" name="token" type="text" class="mt-1 w-full" />
|
||||
@error("token")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
|
||||
<a
|
||||
class="mt-1 text-primary-500"
|
||||
href="https://dropbox.tech/developers/generate-an-access-token-for-your-own-account"
|
||||
target="_blank"
|
||||
>
|
||||
How to generate?
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div x-show="provider === 'ftp'" class="mt-6">
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div class="mt-6">
|
||||
<x-input-label for="host" value="Host" />
|
||||
<x-text-input value="{{ old('host') }}" id="host" name="host" type="text" class="mt-1 w-full" />
|
||||
@error("host")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<x-input-label for="port" value="Port" />
|
||||
<x-text-input value="{{ old('port') }}" id="port" name="port" type="text" class="mt-1 w-full" />
|
||||
@error("port")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<x-input-label for="path" value="Path" />
|
||||
<x-text-input value="{{ old('path') }}" id="path" name="path" type="text" class="mt-1 w-full" />
|
||||
@error("path")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div class="mt-6">
|
||||
<x-input-label for="username" value="Username" />
|
||||
<x-text-input
|
||||
value="{{ old('username') }}"
|
||||
id="username"
|
||||
name="username"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("username")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<x-input-label for="password" value="Password" />
|
||||
<x-text-input
|
||||
value="{{ old('password') }}"
|
||||
id="password"
|
||||
name="password"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
@error("password")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div class="mt-6">
|
||||
<x-input-label for="ssl" :value="__('SSL')" />
|
||||
<x-select-input id="ssl" name="ssl" class="mt-1 w-full">
|
||||
<option value="1" @if(old('ssl')) selected @endif>
|
||||
{{ __("Yes") }}
|
||||
</option>
|
||||
<option value="0" @if(!old('ssl')) selected @endif>
|
||||
{{ __("No") }}
|
||||
</option>
|
||||
</x-select-input>
|
||||
@error("ssl")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<x-input-label for="passive" :value="__('Passive')" />
|
||||
<x-select-input id="passive" name="passive" class="mt-1 w-full">
|
||||
<option value="1" @if(old('passive')) selected @endif>
|
||||
{{ __("Yes") }}
|
||||
</option>
|
||||
<option value="0" @if(!old('passive')) selected @endif>
|
||||
{{ __("No") }}
|
||||
</option>
|
||||
</x-select-input>
|
||||
@error("passive")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-primary-button id="btn-connect-storage-provider" class="ml-3">
|
||||
{{ __("Connect") }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
||||
</div>
|
@ -0,0 +1,18 @@
|
||||
<x-modal name="delete-provider" :show="$errors->isNotEmpty()">
|
||||
<form id="delete-provider-form" method="post" x-bind:action="deleteAction" class="p-6">
|
||||
@csrf
|
||||
@method("delete")
|
||||
|
||||
<h2 class="text-lg font-medium">Are you sure that you want to delete this provider?</h2>
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
<x-secondary-button type="button" x-on:click="$dispatch('close')">
|
||||
{{ __("Cancel") }}
|
||||
</x-secondary-button>
|
||||
|
||||
<x-danger-button class="ml-3">
|
||||
{{ __("Delete") }}
|
||||
</x-danger-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-modal>
|
@ -0,0 +1,64 @@
|
||||
<div>
|
||||
<x-card-header>
|
||||
<x-slot name="title">Storage Providers</x-slot>
|
||||
<x-slot name="description">You can connect to your storage providers</x-slot>
|
||||
<x-slot name="aside">
|
||||
@include("settings.storage-providers.partials.connect-provider")
|
||||
</x-slot>
|
||||
</x-card-header>
|
||||
<div x-data="{ deleteAction: '' }" class="space-y-3">
|
||||
@if (count($providers) > 0)
|
||||
@foreach ($providers as $provider)
|
||||
<x-item-card>
|
||||
<div class="flex-none">
|
||||
@if ($provider->provider == \App\Enums\StorageProvider::FTP)
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="h-10 w-10 text-gray-600 dark:text-gray-200"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"
|
||||
/>
|
||||
</svg>
|
||||
@else
|
||||
<img
|
||||
src="{{ asset("static/images/" . $provider->provider . ".svg") }}"
|
||||
class="h-10 w-10"
|
||||
alt=""
|
||||
/>
|
||||
@endif
|
||||
</div>
|
||||
<div class="ml-3 flex flex-grow flex-col items-start justify-center">
|
||||
<span class="mb-1">{{ $provider->profile }}</span>
|
||||
<span class="text-sm text-gray-400">
|
||||
<x-datetime :value="$provider->created_at" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="inline">
|
||||
<x-icon-button
|
||||
x-on:click="deleteAction = '{{ route('storage-providers.delete', $provider->id) }}'; $dispatch('open-modal', 'delete-provider')"
|
||||
>
|
||||
<x-heroicon name="o-trash" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</x-item-card>
|
||||
@endforeach
|
||||
|
||||
@include("settings.storage-providers.partials.delete-storage-provider")
|
||||
@else
|
||||
<x-simple-card>
|
||||
<div class="text-center">
|
||||
{{ __("You haven't connected to any storage providers yet!") }}
|
||||
</div>
|
||||
</x-simple-card>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
Reference in New Issue
Block a user