Initial commit

This commit is contained in:
hackerESQ
2024-08-01 13:53:10 -05:00
commit 1984bff865
142 changed files with 17783 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
[x-cloak] {
display: none;
}
+1
View File
@@ -0,0 +1 @@
import './bootstrap';
+4
View File
@@ -0,0 +1,4 @@
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
+3
View File
@@ -0,0 +1,3 @@
# Privacy Policy
Edit this file to define the privacy policy for your application.
+3
View File
@@ -0,0 +1,3 @@
# Terms of Service
Edit this file to define the terms of service for your application.
@@ -0,0 +1,171 @@
<div>
<!-- Generate API Token -->
<x-forms.form-section submit="createApiToken">
<x-slot name="title">
{{ __('Create API Token') }}
</x-slot>
<x-slot name="description">
{{ __('API tokens allow third-party services to authenticate with our application on your behalf.') }}
</x-slot>
<x-slot name="form">
<!-- Token Name -->
<div class="col-span-6 sm:col-span-4">
<x-input id="name" label="{{ __('Token Name') }}" type="text" class="mt-1 block w-full" wire:model="createApiTokenForm.name" autofocus />
</div>
<!-- Token Permissions -->
@if (Laravel\Jetstream\Jetstream::hasPermissions())
<div class="col-span-6">
<label class="pt-0 label label-text font-semibold">
<span>
{{ __('Permissions') }}
</span>
</span>
<div class="mt-2 grid grid-cols-1 md:grid-cols-2 gap-4">
@foreach (Laravel\Jetstream\Jetstream::$permissions as $permission)
<label class="flex items-center">
<x-checkbox wire:model="createApiTokenForm.permissions" :value="$permission"/>
<span class="ms-2 text-sm text-gray-600 dark:text-gray-400">{{ $permission }}</span>
</label>
@endforeach
</div>
</div>
@endif
</x-slot>
<x-slot name="actions">
<x-forms.action-message class="me-3" on="created">
{{ __('Created.') }}
</x-forms.action-message>
<x-button>
{{ __('Create') }}
</x-button>
</x-slot>
</x-forms.form-section>
@if ($this->user->tokens->isNotEmpty())
<x-section-border />
<!-- Manage API Tokens -->
<div class="mt-10 sm:mt-0">
<x-forms.action-section>
<x-slot name="title">
{{ __('Manage API Tokens') }}
</x-slot>
<x-slot name="description">
{{ __('You may delete any of your existing tokens if they are no longer needed.') }}
</x-slot>
<!-- API Token List -->
<x-slot name="content">
<div class="space-y-6">
@foreach ($this->user->tokens->sortBy('name') as $token)
<div class="flex items-center justify-between">
<div class="break-all dark:text-white">
{{ $token->name }}
</div>
<div class="flex items-center ms-2">
@if ($token->last_used_at)
<div class="text-sm text-gray-400">
{{ __('Last used') }} {{ $token->last_used_at->diffForHumans() }}
</div>
@endif
@if (Laravel\Jetstream\Jetstream::hasPermissions())
<button class="cursor-pointer ms-6 text-sm text-gray-400 underline" wire:click="manageApiTokenPermissions({{ $token->id }})">
{{ __('Permissions') }}
</button>
@endif
<button class="cursor-pointer ms-6 text-sm text-red-500" wire:click="confirmApiTokenDeletion({{ $token->id }})">
{{ __('Delete') }}
</button>
</div>
</div>
@endforeach
</div>
</x-slot>
</x-forms.action-section>
</div>
@endif
<!-- Token Value Modal -->
<x-dialog-modal wire:model.live="displayingToken">
<x-slot name="title">
{{ __('API Token') }}
</x-slot>
<x-slot name="content">
<div>
{{ __('Please copy your new API token. For your security, it won\'t be shown again.') }}
</div>
<x-input x-ref="plaintextToken" type="text" readonly :value="$plainTextToken"
class="mt-4 bg-gray-100 px-4 py-2 rounded font-mono text-sm text-gray-500 w-full break-all"
autofocus autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
@showing-token-modal.window="setTimeout(() => $refs.plaintextToken.select(), 250)"
/>
</x-slot>
<x-slot name="footer">
<x-button class="btn-outline" wire:click="$set('displayingToken', false)" wire:loading.attr="disabled">
{{ __('Close') }}
</x-button>
</x-slot>
</x-dialog-modal>
<!-- API Token Permissions Modal -->
<x-dialog-modal wire:model.live="managingApiTokenPermissions">
<x-slot name="title">
{{ __('API Token Permissions') }}
</x-slot>
<x-slot name="content">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
@foreach (Laravel\Jetstream\Jetstream::$permissions as $permission)
<label class="flex items-center">
<x-checkbox wire:model="updateApiTokenForm.permissions" :value="$permission"/>
<span class="ms-2 text-sm text-gray-600 dark:text-gray-400">{{ $permission }}</span>
</label>
@endforeach
</div>
</x-slot>
<x-slot name="footer">
<x-button class="btn-outline" wire:click="$set('managingApiTokenPermissions', false)" wire:loading.attr="disabled">
{{ __('Cancel') }}
</x-button>
<x-button type="submit" class="ms-3" wire:click="updateApiToken" wire:loading.attr="disabled">
{{ __('Save') }}
</x-button>
</x-slot>
</x-dialog-modal>
<!-- Delete Token Confirmation Modal -->
<x-confirmation-modal wire:model.live="confirmingApiTokenDeletion">
<x-slot name="title">
{{ __('Delete API Token') }}
</x-slot>
<x-slot name="content">
{{ __('Are you sure you would like to delete this API token?') }}
</x-slot>
<x-slot name="footer">
<x-button class="btn-outline" wire:click="$toggle('confirmingApiTokenDeletion')" wire:loading.attr="disabled">
{{ __('Cancel') }}
</x-button>
<x-button class="ms-3 btn-error text-white" wire:click="deleteApiToken" wire:loading.attr="disabled">
{{ __('Delete') }}
</x-button>
</x-slot>
</x-confirmation-modal>
</div>
+13
View File
@@ -0,0 +1,13 @@
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
{{ __('API Tokens') }}
</h2>
</x-slot>
<div>
<div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
@livewire('api.api-token-manager')
</div>
</div>
</x-app-layout>
@@ -0,0 +1,27 @@
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-auth-logo />
</x-slot>
<div class="mb-4 text-sm text-gray-600 dark:text-gray-400">
{{ __('This is a secure area of the application. Please confirm your password before continuing.') }}
</div>
<x-errors class="mb-4" />
<form method="POST" action="{{ route('password.confirm') }}">
@csrf
<div>
<x-input id="password" label="{{ __('Password') }}" class="block mt-1 w-full" type="password" name="password" required autocomplete="current-password" autofocus />
</div>
<div class="flex justify-end mt-4">
<x-button type="submit" class="ms-4">
{{ __('Confirm') }}
</x-button>
</div>
</form>
</x-authentication-card>
</x-guest-layout>
@@ -0,0 +1,34 @@
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-auth-logo />
</x-slot>
<div class="mb-4 text-sm text-gray-600 dark:text-gray-400">
{{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }}
</div>
@session('status')
<div class="mb-4 font-medium text-sm text-green-600 dark:text-green-400">
{{ $value }}
</div>
@endsession
<x-errors class="mb-4" />
<form method="POST" action="{{ route('password.email') }}">
@csrf
<div class="block">
<x-input id="email" label="{{ __('Email') }}" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus autocomplete="username" />
</div>
<div class="flex items-center justify-end mt-4">
<x-button>
{{ __('Email Password Reset Link') }}
</x-button>
</div>
</form>
</x-authentication-card>
</x-guest-layout>
+48
View File
@@ -0,0 +1,48 @@
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-auth-logo />
</x-slot>
<x-errors class="mb-4" />
@session('status')
<div class="mb-4 font-medium text-sm text-green-600 dark:text-green-400">
{{ $value }}
</div>
@endsession
<form method="POST" action="{{ route('login') }}">
@csrf
<div>
<x-input id="email" label="{{ __('Email') }}" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus autocomplete="username" />
</div>
<div class="mt-4">
<x-input id="password" label="{{ __('Password') }}" class="block mt-1 w-full" type="password" name="password" required autocomplete="current-password" />
</div>
<div class="block mt-4">
<label for="remember_me" class="flex items-center">
<x-checkbox id="remember_me" name="remember" />
<span class="ms-2 text-sm text-gray-600 dark:text-gray-400">{{ __('Remember me') }}</span>
</label>
</div>
<div class="flex items-center justify-end mt-4">
@if (Route::has('password.request'))
<a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" href="{{ route('password.request') }}">
{{ __('Forgot your password?') }}
</a>
@endif
<x-button type="submit" class="ms-4" >
{{ __('Log in') }}
</x-button>
</div>
</form>
</x-authentication-card>
</x-guest-layout>
+60
View File
@@ -0,0 +1,60 @@
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-auth-logo />
</x-slot>
<x-errors class="mb-4" />
<form method="POST" action="{{ route('register') }}">
@csrf
<div>
<x-input id="name" label="{{ __('Name') }}" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus autocomplete="name" />
</div>
<div class="mt-4">
<x-input id="email" label="{{ __('Email') }}" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autocomplete="username" />
</div>
<div class="mt-4">
<x-input id="password" label="{{ __('Password') }}" class="block mt-1 w-full" type="password" name="password" required autocomplete="new-password" />
</div>
<div class="mt-4">
<x-input id="password_confirmation" label="{{ __('Confirm Password') }}" class="block mt-1 w-full" type="password" name="password_confirmation" required autocomplete="new-password" />
</div>
@if (Laravel\Jetstream\Jetstream::hasTermsAndPrivacyPolicyFeature())
<div class="mt-4">
<label>
<div class="flex items-center">
<x-checkbox name="terms" id="terms" required />
<div class="ms-2">
{!! __('I agree to the :terms_of_service and :privacy_policy', [
'terms_of_service' => '<a target="_blank" href="'.route('terms.show').'" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">'.__('Terms of Service').'</a>',
'privacy_policy' => '<a target="_blank" href="'.route('policy.show').'" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">'.__('Privacy Policy').'</a>',
]) !!}
</div>
</div>
</label>
</div>
@endif
<div class="flex items-center justify-end mt-4">
<a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" href="{{ route('login') }}">
{{ __('Already registered?') }}
</a>
<x-button type="submit" class="ms-4">
{{ __('Register') }}
</x-button>
</div>
</form>
</x-authentication-card>
</x-guest-layout>
@@ -0,0 +1,36 @@
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-auth-logo />
</x-slot>
<x-errors class="mb-4" />
<form method="POST" action="{{ route('password.update') }}">
@csrf
<input type="hidden" name="token" value="{{ $request->route('token') }}">
<div class="block">
<x-input id="email" label="{{ __('Email') }}" class="block mt-1 w-full" type="email" name="email" :value="old('email', $request->email)" required autofocus autocomplete="username" />
</div>
<div class="mt-4">
<x-input id="password" label="{{ __('Password') }}" class="block mt-1 w-full" type="password" name="password" required autocomplete="new-password" />
</div>
<div class="mt-4">
<x-input id="password_confirmation" label="{{ __('Confirm Password') }}" class="block mt-1 w-full" type="password" name="password_confirmation" required autocomplete="new-password" />
</div>
<div class="flex items-center justify-end mt-4">
<x-button>
{{ __('Reset Password') }}
</x-button>
</div>
</form>
</x-authentication-card>
</x-guest-layout>
@@ -0,0 +1,58 @@
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-auth-logo />
</x-slot>
<div x-data="{ recovery: false }">
<div class="mb-4 text-sm text-gray-600 dark:text-gray-400" x-show="! recovery">
{{ __('Please confirm access to your account by entering the authentication code provided by your authenticator application.') }}
</div>
<div class="mb-4 text-sm text-gray-600 dark:text-gray-400" x-cloak x-show="recovery">
{{ __('Please confirm access to your account by entering one of your emergency recovery codes.') }}
</div>
<x-errors class="mb-4" />
<form method="POST" action="{{ route('two-factor.login') }}">
@csrf
<div class="mt-4" x-show="! recovery">
<x-input id="code" label="{{ __('Code') }}" class="block mt-1 w-full" type="text" inputmode="numeric" name="code" autofocus x-ref="code" autocomplete="one-time-code" />
</div>
<div class="mt-4" x-cloak x-show="recovery">
<x-input id="recovery_code" label="{{ __('Recovery Code') }}" class="block mt-1 w-full" type="text" name="recovery_code" x-ref="recovery_code" autocomplete="one-time-code" />
</div>
<div class="flex items-center justify-end mt-4">
<button type="button" class="text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 underline cursor-pointer"
x-show="! recovery"
x-on:click="
recovery = true;
$nextTick(() => { $refs.recovery_code.focus() })
">
{{ __('Use a recovery code') }}
</button>
<button type="button" class="text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 underline cursor-pointer"
x-cloak
x-show="recovery"
x-on:click="
recovery = false;
$nextTick(() => { $refs.code.focus() })
">
{{ __('Use an authentication code') }}
</button>
<x-button type="submit" class="ms-4">
{{ __('Log in') }}
</x-button>
</div>
</form>
</div>
</x-authentication-card>
</x-guest-layout>
@@ -0,0 +1,45 @@
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-auth-logo />
</x-slot>
<div class="mb-4 text-sm text-gray-600 dark:text-gray-400">
{{ __('Before continuing, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }}
</div>
@if (session('status') == 'verification-link-sent')
<div class="mb-4 font-medium text-sm text-green-600 dark:text-green-400">
{{ __('A new verification link has been sent to the email address you provided in your profile settings.') }}
</div>
@endif
<div class="mt-4 flex items-center justify-between">
<form method="POST" action="{{ route('verification.send') }}">
@csrf
<div>
<x-button type="submit" type="submit">
{{ __('Resend Verification Email') }}
</x-button>
</div>
</form>
<div>
<a
href="{{ route('profile.show') }}"
class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800"
>
{{ __('Edit Profile') }}</a>
<form method="POST" action="{{ route('logout') }}" class="inline">
@csrf
<button type="submit" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800 ms-2">
{{ __('Log Out') }}
</button>
</form>
</div>
</div>
</x-authentication-card>
</x-guest-layout>
@@ -0,0 +1,19 @@
<a href="{{ route('dashboard') }}">
<svg id="Layer_1" class="fill-current" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2175.97 336.95" {{ $attributes }}>
<path class="text-inherit" d="M.34,23.63l67.11.08-.34,307.46L0,331.1Z"/>
<path class="text-inherit" d="M334.22,331.47,268,331.4l.18-157.46c0-25.44-11.8-40.37-34.17-40.39-19.3,0-35.1,11.36-42.58,29.34l-.19,168.42L125,331.24l.28-247.82,51.76.06,13.13,23.26h1.75c14.94-18,40.83-29.34,66.71-29.31,48.24.06,75.85,26.84,75.78,82.55Z"/>
<path class="text-inherit" d="M459.81,202.22c9.17,32.47,12.66,47.83,16.15,67.13h1.75c2.66-18.42,6.18-34.64,15-67.09L524.85,83.87l66.23.07L512.73,331.67l-74.12-.08L354.67,83.68l71.49.08Z"/>
<path class="text-inherit" d="M807.5,309.2c-19.31,15.76-43.45,27.58-90.82,27.53-78.07-.09-117.94-44-117.84-129.53.09-80.26,44.88-128,116.37-127.94,63.17.07,99.53,40,99.46,100.55a300.65,300.65,0,0,1-3.12,44.3l-147.82-.17c.84,39,18.36,60.55,60.47,60.6,26.75,0,45.19-12.67,54.41-22.31ZM665.1,180.08l87.28.1V173.6c0-28.95-12.23-44.31-39-44.34C683.58,129.23,666,151.14,665.1,180.08Z"/>
<path class="text-inherit" d="M841.89,156.6c0-40.36,34.73-76.72,92.19-76.66,44.74,0,73.23,15.87,89.44,34.75l-42.59,41.62c-8.76-10.09-25.85-23.27-48.66-23.3-14.91,0-24.57,7.87-24.59,19.27,0,37.29,116.65,24.26,116.56,107.16,0,32.89-26,77.16-97.9,77.08-54.39-.06-87.26-22.9-100.84-37.39L865,253.56c11,12.73,35.05,30.74,64.88,30.77,20.61,0,28.52-9.62,28.53-21C958.48,227.34,841.79,239.06,841.89,156.6Z"/>
<path class="text-inherit" d="M1063.27,252.9l.14-118-31.58,0,0-41.23,32-13.12,22.87-58.31,42.11,0-.08,62.29,61.85.07-.06,50.44-61.84-.07-.14,119.74c0,17.1,9.63,25.89,25.85,25.91,10.53,0,24.13-3.49,33.79-10.93l17,49.58c-8.34,6.13-27.65,15.32-68.88,15.28C1093.89,334.52,1063.21,313,1063.27,252.9Z"/>
<path class="text-primary" d="M2175.77,332.71l-66.23-.07.18-157.47c0-25.44-11.8-40.36-34.17-40.39-19.3,0-35.1,11.37-42.58,29.34l-.19,168.43-66.23-.07.28-247.82,51.76.06L2031.72,108h1.75c14.94-18,40.83-29.34,66.71-29.31,48.24,0,75.85,26.84,75.79,82.54Z"/>
<path class="text-primary" d="M1924.39,84.6l-65.23-.07L1859,247.87h.1c28.85,0,50.32,21.55,50.29,51a47,47,0,0,1-13.95,33.55l29.69,0,.26-225.58Z"/>
<path class="text-primary" d="M1223.65,0,1289,.07l-.11,95.62h1.76c9.66-6.57,27.65-13.56,48.26-13.54,56.14.06,97.78,30.81,97.68,122C1436.5,279.64,1392.14,337,1309.68,337c-40.79,0-65.35-6.21-86.39-15.88Zm147.14,209.38c.06-55.26-19.22-72.83-47.73-72.86-15.35,0-27.2,6.11-33.35,13.12l-.15,131.15c7.46,2.64,15.79,3.52,25,3.53C1349.65,284.36,1370.73,262,1370.79,209.38Z"/>
<path class="text-primary" d="M1624.37,147.38c-8.77-1.76-19.73-2.21-28.5-2.22-20.62,0-43.44,7.85-57.92,19.67l-.19,168-65.79-.07.27-247.82L1524,85l13.56,36.42h1.75c10.12-24.11,31.63-41.63,64.09-41.6a103.79,103.79,0,0,1,21,2.22Z"/>
<path class="text-primary" d="M1815.15,163l-.11,99.13c0,14,5.24,20.18,17.09,20.19h7l-.05,45.62c-10.53,6.56-21.94,8.31-32.9,8.29-23.69,0-37.27-11.44-44.71-26.8h-1.76c-9.22,12.27-27.66,27.6-63.19,27.56-48.25-.06-73.21-33-73.17-68.51.06-57,51.41-83.28,129.48-79.24l0-19.3c0-27.63-15.31-36-35.49-36-23.68,0-36.42,13.56-42.57,28l-46.9-34.71c9.67-13.58,34.27-46.45,89.1-46.39C1780.16,80.89,1815.22,102.86,1815.15,163Zm-62.36,71c-43.42-3.12-64.92,6.94-65,28.43,0,14,9.63,24.14,26.73,24.16,16.23,0,30.71-7.43,38.18-17.51Z"/>
</svg>
</a>
@@ -0,0 +1,18 @@
<a href="/">
<svg class="w-32 fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1244.31 573.74">
<path class="text-inherit" d="M.34,1.42l67.11.07L67.11,309,0,308.88Z"/>
<path class="text-inherit" d="M334.22,230.65,279.15,309.2l-11.16,0,.18-157.46c0-25.44-11.8-40.36-34.17-40.39-19.3,0-35.1,11.36-42.58,29.34l-.19,168.43L125,309l.28-247.81,51.76,0,13.13,23.27h1.75c14.94-18,40.83-29.34,66.71-29.31,48.24.05,75.85,26.84,75.78,82.54Z"/>
<path class="text-inherit" d="M459.81,180c9.17,32.47,12.66,47.82,16.15,67.12h1.75c2.66-18.42,6.18-34.65,15-67.1L524.85,61.65l66.23.08L512.73,309.46l-74.12-.09L354.67,61.46l71.49.08Z"/>
<path class="text-inherit" d="M807.5,287c-19.31,15.77-43.45,27.58-90.82,27.53-78.07-.09-117.94-44-117.84-129.52.09-80.27,44.88-128,116.37-128,63.17.07,99.53,40,99.46,100.56a300.44,300.44,0,0,1-3.12,44.29l-147.82-.16c.84,39,18.36,60.55,60.47,60.59,26.75,0,45.19-12.67,54.41-22.3ZM665.1,157.87l87.28.1v-6.58c0-28.95-12.23-44.32-39-44.35C683.58,107,666,128.92,665.1,157.87Z"/>
<path class="text-inherit" d="M841.89,134.38c0-40.35,34.73-76.72,92.19-76.65,44.74.05,73.23,15.87,89.44,34.75L980.93,134.1c-8.76-10.1-25.85-23.28-48.66-23.3-14.91,0-24.57,7.86-24.59,19.27,0,37.28,116.65,24.25,116.56,107.15,0,32.9-26,77.17-97.9,77.09-54.39-.06-87.26-22.91-100.84-37.4L865,231.34c11,12.73,35.05,30.74,64.88,30.78,20.61,0,28.52-9.62,28.53-21C958.48,205.13,841.79,216.84,841.89,134.38Z"/>
<path class="text-inherit" d="M1063.27,230.69l.14-118-31.58,0,0-41.23,32-13.12L1086.78,0l42.11.05-.08,62.28,61.85.07-.06,50.44-61.84-.07-.14,119.74c0,17.11,9.63,25.89,25.85,25.91,10.53,0,24.13-3.48,33.79-10.93l17,49.59c-8.34,6.13-27.65,15.32-68.88,15.27C1093.89,312.3,1063.21,290.78,1063.27,230.69Z"/>
<path class="text-primary" d="M1244.11,569.49l-66.23-.07.18-157.46c0-25.44-11.8-40.37-34.17-40.39-19.3,0-35.1,11.36-42.58,29.34l-.18,168.42-66.23-.07.27-247.82,51.76.06,13.13,23.26h1.76c14.93-18,40.82-29.35,66.7-29.32,48.25.06,75.85,26.84,75.79,82.55Z"/>
<path class="text-primary" d="M992.73,321.39l-65.23-.08-.18,163.35h.1c28.85,0,50.32,21.56,50.29,51a47,47,0,0,1-14,33.55l29.69,0,.26-225.58Z"/>
<path class="text-primary" d="M292,308.65l51.38-71.83,14,0-.1,95.62H359c9.66-6.57,27.65-13.57,48.26-13.55C463.4,319,505,349.75,504.93,441c-.09,75.44-44.45,132.85-126.91,132.76-40.79,0-65.35-6.22-86.39-15.89ZM439.13,446.17c.06-55.27-19.22-72.83-47.73-72.87-15.35,0-27.2,6.11-33.35,13.13l-.15,131.14c7.46,2.64,15.79,3.53,25,3.54C418,521.15,439.07,498.8,439.13,446.17Z"/>
<path class="text-primary" d="M692.71,384.17c-8.77-1.77-19.73-2.22-28.5-2.23-20.62,0-43.43,7.85-57.92,19.68l-.19,168-65.79-.08.28-247.81,51.75,0,13.56,36.42h1.75c10.12-24.12,31.63-41.64,64.09-41.6a103.09,103.09,0,0,1,21,2.22Z"/>
<path class="text-primary" d="M883.49,399.73l-.11,99.13c0,14,5.24,20.18,17.09,20.2h7l-.05,45.62c-10.53,6.57-21.94,8.31-32.9,8.3-23.69,0-37.27-11.45-44.71-26.81h-1.75c-9.23,12.27-27.67,27.6-63.2,27.56-48.24-.05-73.21-33-73.17-68.5.07-57,51.41-83.28,129.48-79.25l0-19.3c0-27.63-15.31-36-35.48-36-23.69,0-36.42,13.55-42.58,28L696.25,364c9.66-13.59,34.26-46.46,89.09-46.4C848.5,317.67,883.56,339.64,883.49,399.73Zm-62.36,71c-43.42-3.12-64.92,6.95-64.94,28.44,0,14,9.62,24.13,26.72,24.15,16.23,0,30.71-7.42,38.18-17.5Z"/>
</svg>
</a>
@@ -0,0 +1,9 @@
<div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100 dark:bg-gray-900">
<div>
{{ $logo }}
</div>
<div class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white dark:bg-gray-800 shadow-md overflow-hidden sm:rounded-lg">
{{ $slot }}
</div>
</div>
@@ -0,0 +1,17 @@
@props(['id' => null, 'maxWidth' => null])
<x-modal :id="$id" :maxWidth="$maxWidth" {{ $attributes }}>
<div class="px-6 py-4">
<div class="text-lg font-medium text-gray-900 dark:text-gray-100">
{{ $title }}
</div>
<div class="mt-4 text-sm text-gray-600 dark:text-gray-400">
{{ $content }}
</div>
</div>
<div class="flex flex-row justify-end px-6 py-4 text-end">
{{ $footer }}
</div>
</x-modal>
@@ -0,0 +1,10 @@
@props(['on'])
<div x-data="{ shown: false, timeout: null }"
x-init="@this.on('{{ $on }}', () => { clearTimeout(timeout); shown = true; timeout = setTimeout(() => { shown = false }, 2000); })"
x-show.transition.out.opacity.duration.1500ms="shown"
x-transition:leave.opacity.duration.1500ms
style="display: none;"
{{ $attributes->merge(['class' => 'text-sm text-gray-600 dark:text-gray-400']) }}>
{{ $slot->isEmpty() ? 'Saved.' : $slot }}
</div>
@@ -0,0 +1,12 @@
<div {{ $attributes->merge(['class' => 'md:grid md:grid-cols-3 md:gap-6']) }}>
<x-forms.section-title>
<x-slot name="title">{{ $title }}</x-slot>
<x-slot name="description">{{ $description }}</x-slot>
</x-forms.section-title>
<div class="mt-5 md:mt-0 md:col-span-2">
<div class="px-4 py-5 sm:p-6 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
{{ $content }}
</div>
</div>
</div>
@@ -0,0 +1,48 @@
@props(['title' => __('Confirm Password'), 'content' => __('For your security, please confirm your password to continue.'), 'button' => __('Confirm')])
@php
$confirmableId = md5($attributes->wire('then'));
@endphp
<span
{{ $attributes->wire('then') }}
x-data
x-ref="span"
x-on:click="$wire.startConfirmingPassword('{{ $confirmableId }}')"
x-on:password-confirmed.window="setTimeout(() => $event.detail.id === '{{ $confirmableId }}' && $refs.span.dispatchEvent(new CustomEvent('then', { bubbles: false })), 250);"
>
{{ $slot }}
</span>
@once
<x-dialog-modal wire:model.live="confirmingPassword">
<x-slot name="title">
{{ $title }}
</x-slot>
<x-slot name="content">
{{ $content }}
<div class="mt-4" x-data="{}" x-on:confirming-password.window="setTimeout(() => $refs.confirmable_password.focus(), 250)">
<x-input type="password" class="mt-1 block w-3/4" placeholder="{{ __('Password') }}" autocomplete="current-password"
x-ref="confirmable_password"
wire:model="confirmablePassword"
wire:keydown.enter="confirmPassword"
error-field="confirmable_password"
/>
</div>
</x-slot>
<x-slot name="footer">
<x-button class="btn-outline" wire:click="stopConfirmingPassword" wire:loading.attr="disabled">
{{ __('Cancel') }}
</x-button>
<x-button type="submit" class="ms-3" dusk="confirm-password-button" wire:click="confirmPassword" wire:loading.attr="disabled">
{{ $button }}
</x-button>
</x-slot>
</x-dialog-modal>
@endonce
@@ -0,0 +1,24 @@
@props(['submit'])
<div {{ $attributes->merge(['class' => 'md:grid md:grid-cols-3 md:gap-6']) }}>
<x-forms.section-title>
<x-slot name="title">{{ $title }}</x-slot>
<x-slot name="description">{{ $description }}</x-slot>
</x-forms.section-title>
<div class="mt-5 md:mt-0 md:col-span-2">
<form wire:submit="{{ $submit }}">
<div class="px-4 py-5 bg-white dark:bg-gray-800 sm:p-6 shadow {{ isset($actions) ? 'sm:rounded-tl-md sm:rounded-tr-md' : 'sm:rounded-md' }}">
<div class="grid grid-cols-6 gap-6">
{{ $form }}
</div>
</div>
@if (isset($actions))
<div class="flex items-center justify-end px-4 py-3 bg-gray-50 dark:bg-gray-800 text-end sm:px-6 shadow sm:rounded-bl-md sm:rounded-br-md">
{{ $actions }}
</div>
@endif
</form>
</div>
</div>
@@ -0,0 +1,13 @@
<div class="md:col-span-1 flex justify-between">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">{{ $title }}</h3>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
{{ $description }}
</p>
</div>
<div class="px-4 sm:px-0">
{{ $aside ?? '' }}
</div>
</div>
@@ -0,0 +1,40 @@
<div class="bg-base-100 border-base-300 border-b sticky top-0 z-10">
<div class="flex justify-between items-center px-6 py-5 mx-auto">
<div class="flex-1 flex items-center">
<label for="main-drawer" class="lg:hidden mr-3">
<x-icon name="o-bars-3" class="cursor-pointer" />
</label>
<x-application-logo style="height:1.3em" />
</div>
<div class="flex flex-grow gap-4 w-50">
<x-spotlight
shortcut="slash"
search-text="{{ __('Search holdings, portfolios, or anything else...') }}"
no-results-text="{{ __('Darn! Nothing found for that search.') }}"
/>
<x-button
icon="o-magnifying-glass"
@click.stop="$dispatch('mary-search-open')"
class="btn-sm"
>
<x-slot:label>
@lang('Press :key to search', ['key' => '<kbd class="kbd kbd-sm">/</kbd>'])
</x-slot:label>
</x-button>
</div>
<div class="flex items-center gap-4">
<x-theme-toggle
title="{{ __('Toggle Theme') }}"
class="btn-circle btn-ghost btn-sm"
darkTheme="dark" lightTheme="nord"
/>
</div>
</div>
</div>
@@ -0,0 +1,45 @@
<x-menu activate-by-route>
<x-menu-item title="{{ __('Dashboard') }}" icon="o-home" link="{{ @route('dashboard') }}" />
<x-menu-sub title="{{ __('Portfolios') }}" icon="o-document-duplicate">
@foreach (auth()->user()->portfolios as $portfolio)
<x-menu-item title="{{ $portfolio->title }}" icon="o-document" link="{{ route('portfolio.show', ['portfolio' => $portfolio->id ]) }}" />
@endforeach
<x-menu-item title="{{ __('Create Portfolio') }}" icon="o-document-plus" link="{{ @route('portfolio.create') }}" />
</x-menu-sub>
<x-menu-item title="{{ __('Transactions') }}" icon="o-banknotes" link="####" />
<x-menu-item title="{{ __('Reporting') }}" icon="o-chart-bar-square" link="####" />
</x-menu>
</div>
<div class="p-4">
<x-menu-separator />
@php
$user = auth()->user();
@endphp
<x-list-item :item="$user" avatar="profile_photo_url" value="name" sub-value="email" no-separator no-hover class="-mx-2 !-my-2 rounded">
<x-slot:actions>
<x-dropdown>
<x-slot:trigger>
<x-button icon="o-cog-6-tooth" class="btn-circle btn-ghost btn-xs" />
</x-slot:trigger>
<x-menu-item title="{{ __('Manage Profile') }}" icon="o-user" link="{{ @route('profile.show') }}" />
<x-menu-item title="{{ __('Import / Export Data') }}" icon="o-cloud-arrow-down" link="{{ @route('profile.show') }}" />
<x-menu-separator />
<x-menu-item title="{{ __('Logout') }}" icon="o-power" onclick="event.preventDefault(); document.getElementById('logout').submit();" />
<form id="logout" action="{{ route('logout') }}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
</x-dropdown>
</x-slot:actions>
</x-list-item>
@@ -0,0 +1,6 @@
<div class="hidden sm:block">
<div {{ $attributes->merge(['class' => 'py-8']) }}>
<div class="border-t border-gray-200 dark:border-gray-700"></div>
</div>
</div>
+105
View File
@@ -0,0 +1,105 @@
<x-app-layout>
<div class="">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-xl sm:rounded-lg">
<div class="p-6 lg:p-8 bg-white dark:bg-gray-800 dark:bg-gradient-to-bl dark:from-gray-700/50 dark:via-transparent border-b border-gray-200 dark:border-gray-700">
<h1 class="mt-3 text-2xl font-medium text-gray-900 dark:text-white">
Welcome to your Jetstream application!
</h1>
<p class="mt-6 text-gray-500 dark:text-gray-400 leading-relaxed">
Laravel Jetstream provides a beautiful, robust starting point for your next Laravel application. Laravel is designed
to help you build your application using a development environment that is simple, powerful, and enjoyable. We believe
you should love expressing your creativity through programming, so we have spent time carefully crafting the Laravel
ecosystem to be a breath of fresh air. We hope you love it.
</p>
</div>
<div class="bg-gray-200 dark:bg-gray-800 bg-opacity-25 grid grid-cols-1 md:grid-cols-2 gap-6 lg:gap-8 p-6 lg:p-8">
<div>
<div class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" class="w-6 h-6 stroke-gray-400">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" />
</svg>
<h2 class="ms-3 text-xl font-semibold text-gray-900 dark:text-white">
<a href="https://laravel.com/docs">Documentation</a>
</h2>
</div>
<p class="mt-4 text-gray-500 dark:text-gray-400 text-sm leading-relaxed">
Laravel has wonderful documentation covering every aspect of the framework. Whether you're new to the framework or have previous experience, we recommend reading all of the documentation from beginning to end.
</p>
<p class="mt-4 text-sm">
<a href="https://laravel.com/docs" class="inline-flex items-center font-semibold text-indigo-700 dark:text-indigo-300">
Explore the documentation
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="ms-1 w-5 h-5 fill-indigo-500 dark:fill-indigo-200">
<path fill-rule="evenodd" d="M5 10a.75.75 0 01.75-.75h6.638L10.23 7.29a.75.75 0 111.04-1.08l3.5 3.25a.75.75 0 010 1.08l-3.5 3.25a.75.75 0 11-1.04-1.08l2.158-1.96H5.75A.75.75 0 015 10z" clip-rule="evenodd" />
</svg>
</a>
</p>
</div>
<div>
<div class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" class="w-6 h-6 stroke-gray-400">
<path stroke-linecap="round" d="M15.75 10.5l4.72-4.72a.75.75 0 011.28.53v11.38a.75.75 0 01-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25h-9A2.25 2.25 0 002.25 7.5v9a2.25 2.25 0 002.25 2.25z" />
</svg>
<h2 class="ms-3 text-xl font-semibold text-gray-900 dark:text-white">
<a href="https://laracasts.com">Laracasts</a>
</h2>
</div>
<p class="mt-4 text-gray-500 dark:text-gray-400 text-sm leading-relaxed">
Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process.
</p>
<p class="mt-4 text-sm">
<a href="https://laracasts.com" class="inline-flex items-center font-semibold text-indigo-700 dark:text-indigo-300">
Start watching Laracasts
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="ms-1 w-5 h-5 fill-indigo-500 dark:fill-indigo-200">
<path fill-rule="evenodd" d="M5 10a.75.75 0 01.75-.75h6.638L10.23 7.29a.75.75 0 111.04-1.08l3.5 3.25a.75.75 0 010 1.08l-3.5 3.25a.75.75 0 11-1.04-1.08l2.158-1.96H5.75A.75.75 0 015 10z" clip-rule="evenodd" />
</svg>
</a>
</p>
</div>
<div>
<div class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" class="w-6 h-6 stroke-gray-400">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
</svg>
<h2 class="ms-3 text-xl font-semibold text-gray-900 dark:text-white">
<a href="https://tailwindcss.com/">Tailwind</a>
</h2>
</div>
<p class="mt-4 text-gray-500 dark:text-gray-400 text-sm leading-relaxed">
Laravel Jetstream is built with Tailwind, an amazing utility first CSS framework that doesn't get in your way. You'll be amazed how easily you can build and maintain fresh, modern designs with this wonderful framework at your fingertips.
</p>
</div>
<div>
<div class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" class="w-6 h-6 stroke-gray-400">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z" />
</svg>
<h2 class="ms-3 text-xl font-semibold text-gray-900 dark:text-white">
Authentication
</h2>
</div>
<p class="mt-4 text-gray-500 dark:text-gray-400 text-sm leading-relaxed">
Authentication and registration views are included with Laravel Jetstream, as well as support for user email verification and resetting forgotten passwords. So, you're free to get started with what matters most: building your application.
</p>
</div>
</div>
</div>
</div>
</div>
</x-app-layout>
+25
View File
@@ -0,0 +1,25 @@
<x-common-layout>
<x-slot:body class="min-h-screen font-sans antialiased bg-base-200/50 dark:bg-base-200" x-data>
<div>
<x-partials.nav-bar />
<x-main with-nav full-width>
<x-slot:sidebar drawer="main-drawer" class="bg-base-100 lg:bg-inherit">
<x-partials.side-bar />
</x-slot:sidebar>
<x-slot:content>
{{ $slot }}
</x-slot:content>
</x-main>
<x-toast />
</div>
</x-slot:body>
</x-common-layout>
+27
View File
@@ -0,0 +1,27 @@
{{-- <!DOCTYPE html> --}}
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
<!-- Scripts -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
<!-- Styles -->
@livewireStyles
</head>
<body {{ $attributes->merge(['class']) }}>
{{ $body }}
@livewireScripts
</body>
</html>
+9
View File
@@ -0,0 +1,9 @@
<x-common-layout>
<x-slot:body class="font-sans text-gray-900 dark:text-gray-100 antialiased">
{{ $slot }}
<x-theme-toggle class="hidden" darkTheme="dark" lightTheme="nord"/>
</x-slot:body>
</x-common-layout>
View File
@@ -0,0 +1,5 @@
<x-app-layout>
<livewire:portfolio.manage-portfolio-form submit="save" />
</x-app-layout>
@@ -0,0 +1,93 @@
<?php
use App\Models\Category;
use App\Models\Portfolio;
use App\Models\User;
use Illuminate\Support\Collection;
use Livewire\Attributes\Rule;
use Livewire\Volt\Component;
use Mary\Traits\Toast;
new class extends Component {
use Toast;
public string $submit;
public ?Portfolio $portfolio;
#[Rule('required|min:5')]
public string $title;
#[Rule('sometimes|nullable')]
public ?string $notes;
public function mount() {
if (isset($this->portfolio)) {
$this->title = $this->portfolio->title;
$this->notes = $this->portfolio->notes;
}
}
public function categories(): Collection
{
return Category::all();
}
public function update()
{
$this->portfolio->update($this->validate());
// $this->portfolio->owner_id = auth()->user()->id;
$this->portfolio->save();
$this->success('Portfolio updated.', redirectTo: "/portfolio/{$this->portfolio->id}");
}
public function save()
{
// // get stats
// $key = 'portfolio-metrics-' . $portfolio->id;
// $metrics = cache()->remember($key, 60, function () use ($portfolio) {
// return Holding::where(['portfolio_id' => $portfolio->id])
// ->getPortfolioMetrics()
// ->first();
// });
// return view('pages.portfolios.show', [
// 'portfolio' => $portfolio,
// 'metrics' => $metrics
// ]);
$portfolio = (new Portfolio())->fill($this->validate());
// $portfolio->owner_id = auth()->user()->id;
$portfolio->save();
$this->success('Portfolio created.', redirectTo: "/portfolio/{$portfolio->id}");
}
public function with(): array
{
return [
// 'categories' => $this->categories()
];
}
}; ?>
<div class="grid lg:grid-cols-4 gap-10">
<x-form wire:submit="{{ $submit }}" class="col-span-3">
<x-input label="Title" wire:model="title" />
{{-- <x-select label="Category" wire:model="category_id" placeholder="Select a category" :options="$categories" /> --}}
<x-textarea label="Body" wire:model="notes" rows="5" />
<x-slot:actions>
<x-button label="Cancel" link="{{ url()->previous() }}" />
<x-button label="{{ $submit == 'save' ? 'Create' : 'Update' }}" type="submit" icon="o-paper-airplane" class="btn-primary" spinner="save" />
</x-slot:actions>
</x-form>
</div>
@@ -0,0 +1,5 @@
<x-app-layout>
<livewire:portfolio.manage-portfolio-form :portfolio="$portfolio" submit="update" />
</x-app-layout>
+13
View File
@@ -0,0 +1,13 @@
<x-guest-layout>
<div class="pt-4 bg-gray-100 dark:bg-gray-900">
<div class="min-h-screen flex flex-col items-center pt-6 sm:pt-0">
<div>
<x-auth-logo />
</div>
<div class="w-full sm:max-w-2xl mt-6 p-6 bg-white dark:bg-gray-800 shadow-md overflow-hidden sm:rounded-lg prose dark:prose-invert">
{!! $policy !!}
</div>
</div>
</div>
</x-guest-layout>
@@ -0,0 +1,52 @@
<x-forms.action-section>
<x-slot name="title">
{{ __('Delete Account') }}
</x-slot>
<x-slot name="description">
{{ __('Permanently delete your account.') }}
</x-slot>
<x-slot name="content">
<div class="max-w-xl text-sm text-gray-600 dark:text-gray-400">
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.') }}
</div>
<div class="mt-5">
<x-button class="btn-error text-white" wire:click="confirmUserDeletion" wire:loading.attr="disabled">
{{ __('Delete Account') }}
</x-button>
</div>
<!-- Delete User Confirmation Modal -->
<x-dialog-modal wire:model.live="confirmingUserDeletion">
<x-slot name="title">
{{ __('Delete Account') }}
</x-slot>
<x-slot name="content">
{{ __('Are you sure you want to delete your account? Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }}
<div class="mt-4" x-data="{}" x-on:confirming-delete-user.window="setTimeout(() => $refs.password.focus(), 250)">
<x-input type="password" class="mt-1 block w-3/4"
autocomplete="current-password"
placeholder="{{ __('Password') }}"
x-ref="password"
wire:model="password"
wire:keydown.enter="deleteUser" />
</div>
</x-slot>
<x-slot name="footer">
<x-button class="btn-outline" wire:click="$toggle('confirmingUserDeletion')" wire:loading.attr="disabled">
{{ __('Cancel') }}
</x-button>
<x-button class="ms-3 btn-error text-white" wire:click="deleteUser" wire:loading.attr="disabled">
{{ __('Delete Account') }}
</x-button>
</x-slot>
</x-dialog-modal>
</x-slot>
</x-forms.action-section>
@@ -0,0 +1,97 @@
<x-forms.action-section>
<x-slot name="title">
{{ __('Browser Sessions') }}
</x-slot>
<x-slot name="description">
{{ __('Manage and log out your active sessions on other browsers and devices.') }}
</x-slot>
<x-slot name="content">
<div class="max-w-xl text-sm text-gray-600 dark:text-gray-400">
{{ __('If necessary, you may log out of all of your other browser sessions across all of your devices. Some of your recent sessions are listed below; however, this list may not be exhaustive. If you feel your account has been compromised, you should also update your password.') }}
</div>
@if (count($this->sessions) > 0)
<div class="mt-5 space-y-6">
<!-- Other Browser Sessions -->
@foreach ($this->sessions as $session)
<div class="flex items-center">
<div>
@if ($session->agent->isDesktop())
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-8 h-8 text-gray-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 17.25v1.007a3 3 0 01-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0115 18.257V17.25m6-12V15a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15V5.25m18 0A2.25 2.25 0 0018.75 3H5.25A2.25 2.25 0 003 5.25m18 0V12a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 12V5.25" />
</svg>
@else
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-8 h-8 text-gray-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 1.5H8.25A2.25 2.25 0 006 3.75v16.5a2.25 2.25 0 002.25 2.25h7.5A2.25 2.25 0 0018 20.25V3.75a2.25 2.25 0 00-2.25-2.25H13.5m-3 0V3h3V1.5m-3 0h3m-3 18.75h3" />
</svg>
@endif
</div>
<div class="ms-3">
<div class="text-sm text-gray-600 dark:text-gray-400">
{{ $session->agent->platform() ? $session->agent->platform() : __('Unknown') }} - {{ $session->agent->browser() ? $session->agent->browser() : __('Unknown') }}
</div>
<div>
<div class="text-xs text-gray-500">
{{ $session->ip_address }},
@if ($session->is_current_device)
<span class="text-green-500 font-semibold">{{ __('This device') }}</span>
@else
{{ __('Last active') }} {{ $session->last_active }}
@endif
</div>
</div>
</div>
</div>
@endforeach
</div>
@endif
<div class="flex items-center mt-5">
<x-button type="submit" wire:click="confirmLogout" wire:loading.attr="disabled">
{{ __('Log Out Other Browser Sessions') }}
</x-button>
<x-forms.action-message class="ms-3" on="loggedOut">
{{ __('Done.') }}
</x-forms.action-message>
</div>
<!-- Log Out Other Devices Confirmation Modal -->
<x-dialog-modal wire:model.live="confirmingLogout">
<x-slot name="title">
{{ __('Log Out Other Browser Sessions') }}
</x-slot>
<x-slot name="content">
{{ __('Please enter your password to confirm you would like to log out of your other browser sessions across all of your devices.') }}
<div class="mt-4" x-data="{}" x-on:confirming-logout-other-browser-sessions.window="setTimeout(() => $refs.password.focus(), 250)">
<x-input type="password" class="mt-1 block w-3/4"
autocomplete="current-password"
placeholder="{{ __('Password') }}"
x-ref="password"
wire:model="password"
wire:keydown.enter="logoutOtherBrowserSessions" />
</div>
</x-slot>
<x-slot name="footer">
<x-button class="btn-outline" wire:click="$toggle('confirmingLogout')" wire:loading.attr="disabled">
{{ __('Cancel') }}
</x-button>
<x-button type="submit" class="ms-3"
wire:click="logoutOtherBrowserSessions"
wire:loading.attr="disabled">
{{ __('Log Out Other Browser Sessions') }}
</x-button>
</x-slot>
</x-dialog-modal>
</x-slot>
</x-forms.action-section>
+40
View File
@@ -0,0 +1,40 @@
<x-app-layout>
<div>
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
@if (Laravel\Fortify\Features::canUpdateProfileInformation())
@livewire('profile.update-profile-information-form')
<x-section-border />
@endif
@if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::updatePasswords()))
<div class="mt-10 sm:mt-0">
@livewire('profile.update-password-form')
</div>
<x-section-border />
@endif
@if (Laravel\Fortify\Features::canManageTwoFactorAuthentication())
<div class="mt-10 sm:mt-0">
@livewire('profile.two-factor-authentication-form')
</div>
<x-section-border />
@endif
<div class="mt-10 sm:mt-0">
@livewire('profile.logout-other-browser-sessions-form')
</div>
@if (Laravel\Jetstream\Jetstream::hasAccountDeletionFeatures())
<x-section-border />
<div class="mt-10 sm:mt-0">
@livewire('profile.delete-user-form')
</div>
@endif
</div>
</div>
</x-app-layout>
@@ -0,0 +1,123 @@
<x-forms.action-section>
<x-slot name="title">
{{ __('Two Factor Authentication') }}
</x-slot>
<x-slot name="description">
{{ __('Add additional security to your account using two factor authentication.') }}
</x-slot>
<x-slot name="content">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">
@if ($this->enabled)
@if ($showingConfirmation)
{{ __('Finish enabling two factor authentication.') }}
@else
{{ __('You have enabled two factor authentication.') }}
@endif
@else
{{ __('You have not enabled two factor authentication.') }}
@endif
</h3>
<div class="mt-3 max-w-xl text-sm text-gray-600 dark:text-gray-400">
<p>
{{ __('When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone\'s Google Authenticator application.') }}
</p>
</div>
@if ($this->enabled)
@if ($showingQrCode)
<div class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
<p class="font-semibold">
@if ($showingConfirmation)
{{ __('To finish enabling two factor authentication, scan the following QR code using your phone\'s authenticator application or enter the setup key and provide the generated OTP code.') }}
@else
{{ __('Two factor authentication is now enabled. Scan the following QR code using your phone\'s authenticator application or enter the setup key.') }}
@endif
</p>
</div>
<div class="mt-4 p-2 inline-block bg-white">
{!! $this->user->twoFactorQrCodeSvg() !!}
</div>
<div class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
<p class="font-semibold">
{{ __('Setup Key') }}: {{ decrypt($this->user->two_factor_secret) }}
</p>
</div>
@if ($showingConfirmation)
<div class="mt-4">
<x-input id="code" label="{{ __('Code') }}" type="text" name="code" class="block mt-1 w-1/2" inputmode="numeric" autofocus autocomplete="one-time-code"
wire:model="code"
wire:keydown.enter="confirmTwoFactorAuthentication" />
</div>
@endif
@endif
@if ($showingRecoveryCodes)
<div class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
<p class="font-semibold">
{{ __('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.') }}
</p>
</div>
<div class="grid gap-1 max-w-xl mt-4 px-4 py-4 font-mono text-sm bg-gray-100 dark:bg-gray-900 dark:text-gray-100 rounded-lg">
@foreach (json_decode(decrypt($this->user->two_factor_recovery_codes), true) as $code)
<div>{{ $code }}</div>
@endforeach
</div>
@endif
@endif
<div class="mt-5">
@if (! $this->enabled)
<x-forms.confirms-password wire:then="enableTwoFactorAuthentication">
<x-button type="button" wire:loading.attr="disabled">
{{ __('Enable') }}
</x-button>
</x-forms.confirms-password>
@else
@if ($showingRecoveryCodes)
<x-forms.confirms-password wire:then="regenerateRecoveryCodes">
<x-button class="btn-outline" class="me-3">
{{ __('Regenerate Recovery Codes') }}
</x-button>
</x-forms.confirms-password>
@elseif ($showingConfirmation)
<x-forms.confirms-password wire:then="confirmTwoFactorAuthentication">
<x-button type="button" class="me-3" wire:loading.attr="disabled">
{{ __('Confirm') }}
</x-button>
</x-forms.confirms-password>
@else
<x-forms.confirms-password wire:then="showRecoveryCodes">
<x-button class="btn-outline" class="me-3">
{{ __('Show Recovery Codes') }}
</x-button>
</x-forms.confirms-password>
@endif
@if ($showingConfirmation)
<x-forms.confirms-password wire:then="disableTwoFactorAuthentication">
<x-button class="btn-outline" wire:loading.attr="disabled">
{{ __('Cancel') }}
</x-button>
</x-forms.confirms-password>
@else
<x-forms.confirms-password wire:then="disableTwoFactorAuthentication">
<x-button class="btn-error text-white" wire:loading.attr="disabled">
{{ __('Disable') }}
</x-button>
</x-forms.confirms-password>
@endif
@endif
</div>
</x-slot>
</x-forms.action-section>
@@ -0,0 +1,40 @@
<x-forms.form-section submit="updatePassword">
<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>
<x-slot name="form">
<div class="col-span-6 sm:col-span-4">
<x-input id="current_password" label="{{ __('Current Password') }}" type="password" class="mt-1 block w-full" wire:model="state.current_password" error-field="current_password" autocomplete="current-password" />
</div>
<div class="col-span-6 sm:col-span-4">
<x-input id="password" label="{{ __('New Password') }}" type="password" class="mt-1 block w-full" wire:model="state.password" error-field="password" autocomplete="new-password" />
</div>
<div class="col-span-6 sm:col-span-4">
<x-input id="password_confirmation" label="{{ __('Confirm Password') }}" type="password" class="mt-1 block w-full" wire:model="state.password_confirmation" error-field="password_confirmation" autocomplete="new-password" />
</div>
</x-slot>
<x-slot name="actions">
<x-forms.action-message class="me-3" on="saved">
{{ __('Saved.') }}
</x-forms.action-message>
<x-button type="submit">
{{ __('Save') }}
</x-button>
</x-slot>
</x-forms.form-section>
@@ -0,0 +1,97 @@
<x-forms.form-section submit="updateProfileInformation">
<x-slot name="title">
{{ __('Profile Information') }}
</x-slot>
<x-slot name="description">
{{ __('Update your account\'s profile information and email address.') }}
</x-slot>
<x-slot name="form">
<!-- Profile Photo -->
@if (Laravel\Jetstream\Jetstream::managesProfilePhotos())
<div x-data="{photoName: null, photoPreview: null}" class="col-span-6 sm:col-span-4">
<!-- Profile Photo File Input -->
<input type="file" id="photo" class="hidden"
wire:model.live="photo"
x-ref="photo"
x-on:change="
photoName = $refs.photo.files[0].name;
const reader = new FileReader();
reader.onload = (e) => {
photoPreview = e.target.result;
};
reader.readAsDataURL($refs.photo.files[0]);
" />
<label for="photo" class="pt-0 label label-text font-semibold">
<span>{{ __('Photo') }} </span>
</label>
<!-- Current Profile Photo -->
<div class="mt-2" x-show="! photoPreview">
<img src="{{ $this->user->profile_photo_url }}" alt="{{ $this->user->name }}" class="rounded-full h-20 w-20 object-cover">
</div>
<!-- New Profile Photo Preview -->
<div class="mt-2" x-show="photoPreview" style="display: none;">
<span class="block rounded-full w-20 h-20 bg-cover bg-no-repeat bg-center"
x-bind:style="'background-image: url(\'' + photoPreview + '\');'">
</span>
</div>
<x-button class="btn-outline" class="mt-2 me-2" type="button" x-on:click.prevent="$refs.photo.click()">
{{ __('Select A New Photo') }}
</x-button>
@if ($this->user->profile_photo_path)
<x-button class="btn-outline" type="button" class="mt-2" wire:click="deleteProfilePhoto">
{{ __('Remove Photo') }}
</x-button>
@endif
@if ($errors->has('photo') && is_array($errors->get('photo')))
<p class="text-sm text-red-600 dark:text-red-400">{{ $errors->get('photo')[0] }}</p>
@endif
</div>
@endif
<!-- Name -->
<div class="col-span-6 sm:col-span-4">
<x-input id="name" label="{{ __('Name') }}" type="text" class="mt-1 block w-full" wire:model="state.name" error-field="name" required autocomplete="name" />
</div>
<!-- Email -->
<div class="col-span-6 sm:col-span-4">
<x-input id="email" label="{{ __('Email') }}" type="email" class="mt-1 block w-full" wire:model="state.email" error-field="email" required autocomplete="username" />
@if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::emailVerification()) && ! $this->user->hasVerifiedEmail())
<p class="text-sm mt-2 dark:text-white">
{{ __('Your email address is unverified.') }}
<button type="button" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" wire:click.prevent="sendEmailVerification">
{{ __('Click here to re-send the verification email.') }}
</button>
</p>
@if ($this->verificationLinkSent)
<p class="mt-2 font-medium text-sm text-green-600 dark:text-green-400">
{{ __('A new verification link has been sent to your email address.') }}
</p>
@endif
@endif
</div>
</x-slot>
<x-slot name="actions">
<x-forms.action-message class="me-3" on="saved">
{{ __('Saved.') }}
</x-forms.action-message>
<x-button type="submit" wire:loading.attr="disabled" wire:target="photo">
{{ __('Save') }}
</x-button>
</x-slot>
</x-forms.form-section>
+13
View File
@@ -0,0 +1,13 @@
<x-guest-layout>
<div class="pt-4 bg-gray-100 dark:bg-gray-900">
<div class="min-h-screen flex flex-col items-center pt-6 sm:pt-0">
<div>
<x-auth-logo />
</div>
<div class="w-full sm:max-w-2xl mt-6 p-6 bg-white dark:bg-gray-800 shadow-md overflow-hidden sm:rounded-lg prose dark:prose-invert">
{!! $terms !!}
</div>
</div>
</div>
</x-guest-layout>
File diff suppressed because one or more lines are too long