Init
This commit is contained in:
commit
0c705c7235
18
.editorconfig
Normal file
18
.editorconfig
Normal file
@ -0,0 +1,18 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
65
.env.example
Normal file
65
.env.example
Normal file
@ -0,0 +1,65 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
||||
APP_LOCALE=en
|
||||
APP_FALLBACK_LOCALE=en
|
||||
APP_FAKER_LOCALE=en_US
|
||||
|
||||
APP_MAINTENANCE_DRIVER=file
|
||||
# APP_MAINTENANCE_STORE=database
|
||||
|
||||
PHP_CLI_SERVER_WORKERS=4
|
||||
|
||||
BCRYPT_ROUNDS=12
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_STACK=single
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
# DB_HOST=127.0.0.1
|
||||
# DB_PORT=3306
|
||||
# DB_DATABASE=laravel
|
||||
# DB_USERNAME=root
|
||||
# DB_PASSWORD=
|
||||
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
SESSION_ENCRYPT=false
|
||||
SESSION_PATH=/
|
||||
SESSION_DOMAIN=null
|
||||
|
||||
BROADCAST_CONNECTION=log
|
||||
FILESYSTEM_DISK=local
|
||||
QUEUE_CONNECTION=database
|
||||
|
||||
CACHE_STORE=database
|
||||
# CACHE_PREFIX=
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_CLIENT=phpredis
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=log
|
||||
MAIL_SCHEME=null
|
||||
MAIL_HOST=127.0.0.1
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
10
.gitattributes
vendored
Normal file
10
.gitattributes
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
* text=auto eol=lf
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
*.html diff=html
|
||||
*.md diff=markdown
|
||||
*.php diff=php
|
||||
|
||||
CHANGELOG.md export-ignore
|
||||
README.md export-ignore
|
46
.github/workflows/lint.yml
vendored
Normal file
46
.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
name: linter
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
quality:
|
||||
runs-on: ubuntu-latest
|
||||
environment: Testing
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.4'
|
||||
|
||||
- name: Add Flux Credentials Loaded From ENV
|
||||
run: composer config http-basic.composer.fluxui.dev "${{ secrets.FLUX_USERNAME }}" "${{ secrets.FLUX_LICENSE_KEY }}"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
npm install
|
||||
|
||||
- name: Run Pint
|
||||
run: vendor/bin/pint
|
||||
|
||||
# - name: Commit Changes
|
||||
# uses: stefanzweifel/git-auto-commit-action@v5
|
||||
# with:
|
||||
# commit_message: fix code style
|
||||
# commit_options: '--no-verify'
|
||||
# file_pattern: |
|
||||
# **/*
|
||||
# !.github/workflows/*
|
54
.github/workflows/tests.yml
vendored
Normal file
54
.github/workflows/tests.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
name: tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
- main
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
environment: Testing
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
tools: composer:v2
|
||||
coverage: xdebug
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install Node Dependencies
|
||||
run: npm i
|
||||
|
||||
- name: Add Flux Credentials Loaded From ENV
|
||||
run: composer config http-basic.composer.fluxui.dev "${{ secrets.FLUX_USERNAME }}" "${{ secrets.FLUX_LICENSE_KEY }}"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: composer install --no-interaction --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: Copy Environment File
|
||||
run: cp .env.example .env
|
||||
|
||||
- name: Generate Application Key
|
||||
run: php artisan key:generate
|
||||
|
||||
- name: Build Assets
|
||||
run: npm run build
|
||||
|
||||
- name: Run Tests
|
||||
run: ./vendor/bin/pest
|
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/.phpunit.cache
|
||||
/node_modules
|
||||
/public/build
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/storage/pail
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpactor.json
|
||||
.phpunit.result.cache
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
/auth.json
|
||||
/.fleet
|
||||
/.idea
|
||||
/.nova
|
||||
/.vscode
|
||||
/.zed
|
30
app/Http/Controllers/Auth/VerifyEmailController.php
Normal file
30
app/Http/Controllers/Auth/VerifyEmailController.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Foundation\Auth\EmailVerificationRequest;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
class VerifyEmailController extends Controller
|
||||
{
|
||||
/**
|
||||
* Mark the authenticated user's email address as verified.
|
||||
*/
|
||||
public function __invoke(EmailVerificationRequest $request): RedirectResponse
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
|
||||
}
|
||||
|
||||
if ($request->user()->markEmailAsVerified()) {
|
||||
/** @var \Illuminate\Contracts\Auth\MustVerifyEmail $user */
|
||||
$user = $request->user();
|
||||
|
||||
event(new Verified($user));
|
||||
}
|
||||
|
||||
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
|
||||
}
|
||||
}
|
8
app/Http/Controllers/Controller.php
Normal file
8
app/Http/Controllers/Controller.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
abstract class Controller
|
||||
{
|
||||
//
|
||||
}
|
14
app/Http/Controllers/HomeController.php
Normal file
14
app/Http/Controllers/HomeController.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
{
|
||||
return view('index');
|
||||
}
|
||||
}
|
22
app/Livewire/Actions/Logout.php
Normal file
22
app/Livewire/Actions/Logout.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Actions;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class Logout
|
||||
{
|
||||
/**
|
||||
* Log the current user out of the application.
|
||||
*/
|
||||
public function __invoke()
|
||||
{
|
||||
Auth::guard('web')->logout();
|
||||
|
||||
Session::invalidate();
|
||||
Session::regenerateToken();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
87
app/Livewire/ApplicationForm.php
Normal file
87
app/Livewire/ApplicationForm.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\Upload;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use Mews\Captcha\Facades\Captcha;
|
||||
|
||||
#[Layout('components.layouts.guest')]
|
||||
class ApplicationForm extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public $photos = [];
|
||||
|
||||
public $message = '';
|
||||
|
||||
public $applicationId;
|
||||
|
||||
public $applicationUuid;
|
||||
|
||||
public $captcha;
|
||||
|
||||
public $captchaInput;
|
||||
|
||||
protected $rules = [
|
||||
'photos' => 'required|array|min:1|max:6',
|
||||
'photos.*' => 'image|max:8192', // 8MB max per photo
|
||||
'message' => 'required|string|max:500',
|
||||
'captchaInput' => 'required',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->refreshCaptcha();
|
||||
}
|
||||
|
||||
public function refreshCaptcha()
|
||||
{
|
||||
$this->captcha = Captcha::src('flat');
|
||||
}
|
||||
|
||||
public function submit()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
// Validate captcha
|
||||
if (!captcha_check($this->captchaInput)) {
|
||||
$this->addError('captchaInput', 'Invalid CAPTCHA.');
|
||||
$this->refreshCaptcha();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create application
|
||||
$application = Application::create([
|
||||
'uuid' => Str::uuid(),
|
||||
'message' => $this->message,
|
||||
]);
|
||||
|
||||
// Save each uploaded photo
|
||||
foreach ($this->photos as $photo) {
|
||||
$path = $photo->store('applications/photos', 'public');
|
||||
|
||||
Upload::create([
|
||||
'application_id' => $application->id,
|
||||
'file_path' => $path,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->applicationId = $application->id;
|
||||
$this->applicationUuid = (string) $application->uuid;
|
||||
|
||||
session()->flash('message', 'Application submitted successfully!');
|
||||
$this->reset(['photos', 'message', 'captchaInput']);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.application-form');
|
||||
}
|
||||
}
|
37
app/Livewire/Auth/ConfirmPassword.php
Normal file
37
app/Livewire/Auth/ConfirmPassword.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth')]
|
||||
class ConfirmPassword extends Component
|
||||
{
|
||||
public string $password = '';
|
||||
|
||||
/**
|
||||
* Confirm the current user's password.
|
||||
*/
|
||||
public function confirmPassword(): void
|
||||
{
|
||||
$this->validate([
|
||||
'password' => ['required', 'string'],
|
||||
]);
|
||||
|
||||
if (! Auth::guard('web')->validate([
|
||||
'email' => Auth::user()->email,
|
||||
'password' => $this->password,
|
||||
])) {
|
||||
throw ValidationException::withMessages([
|
||||
'password' => __('auth.password'),
|
||||
]);
|
||||
}
|
||||
|
||||
session(['auth.password_confirmed_at' => time()]);
|
||||
|
||||
$this->redirectIntended(default: route('dashboard', absolute: false), navigate: true);
|
||||
}
|
||||
}
|
27
app/Livewire/Auth/ForgotPassword.php
Normal file
27
app/Livewire/Auth/ForgotPassword.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth')]
|
||||
class ForgotPassword extends Component
|
||||
{
|
||||
public string $email = '';
|
||||
|
||||
/**
|
||||
* Send a password reset link to the provided email address.
|
||||
*/
|
||||
public function sendPasswordResetLink(): void
|
||||
{
|
||||
$this->validate([
|
||||
'email' => ['required', 'string', 'email'],
|
||||
]);
|
||||
|
||||
Password::sendResetLink($this->only('email'));
|
||||
|
||||
session()->flash('status', __('A reset link will be sent if the account exists.'));
|
||||
}
|
||||
}
|
77
app/Livewire/Auth/Login.php
Normal file
77
app/Livewire/Auth/Login.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use Illuminate\Auth\Events\Lockout;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth')]
|
||||
class Login extends Component
|
||||
{
|
||||
#[Validate('required|string|email')]
|
||||
public string $email = '';
|
||||
|
||||
#[Validate('required|string')]
|
||||
public string $password = '';
|
||||
|
||||
public bool $remember = false;
|
||||
|
||||
/**
|
||||
* Handle an incoming authentication request.
|
||||
*/
|
||||
public function login(): void
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$this->ensureIsNotRateLimited();
|
||||
|
||||
if (! Auth::attempt(['email' => $this->email, 'password' => $this->password], $this->remember)) {
|
||||
RateLimiter::hit($this->throttleKey());
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => __('auth.failed'),
|
||||
]);
|
||||
}
|
||||
|
||||
RateLimiter::clear($this->throttleKey());
|
||||
Session::regenerate();
|
||||
|
||||
$this->redirectIntended(default: route('dashboard', absolute: false), navigate: true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the authentication request is not rate limited.
|
||||
*/
|
||||
protected function ensureIsNotRateLimited(): void
|
||||
{
|
||||
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event(new Lockout(request()));
|
||||
|
||||
$seconds = RateLimiter::availableIn($this->throttleKey());
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => __('auth.throttle', [
|
||||
'seconds' => $seconds,
|
||||
'minutes' => ceil($seconds / 60),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication rate limiting throttle key.
|
||||
*/
|
||||
protected function throttleKey(): string
|
||||
{
|
||||
return Str::transliterate(Str::lower($this->email).'|'.request()->ip());
|
||||
}
|
||||
}
|
43
app/Livewire/Auth/Register.php
Normal file
43
app/Livewire/Auth/Register.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rules;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth')]
|
||||
class Register extends Component
|
||||
{
|
||||
public string $name = '';
|
||||
|
||||
public string $email = '';
|
||||
|
||||
public string $password = '';
|
||||
|
||||
public string $password_confirmation = '';
|
||||
|
||||
/**
|
||||
* Handle an incoming registration request.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$validated = $this->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
|
||||
'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()],
|
||||
]);
|
||||
|
||||
$validated['password'] = Hash::make($validated['password']);
|
||||
|
||||
event(new Registered(($user = User::create($validated))));
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
$this->redirect(route('dashboard', absolute: false), navigate: true);
|
||||
}
|
||||
}
|
76
app/Livewire/Auth/ResetPassword.php
Normal file
76
app/Livewire/Auth/ResetPassword.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth')]
|
||||
class ResetPassword extends Component
|
||||
{
|
||||
#[Locked]
|
||||
public string $token = '';
|
||||
|
||||
public string $email = '';
|
||||
|
||||
public string $password = '';
|
||||
|
||||
public string $password_confirmation = '';
|
||||
|
||||
/**
|
||||
* Mount the component.
|
||||
*/
|
||||
public function mount(string $token): void
|
||||
{
|
||||
$this->token = $token;
|
||||
|
||||
$this->email = request()->string('email');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the password for the given user.
|
||||
*/
|
||||
public function resetPassword(): void
|
||||
{
|
||||
$this->validate([
|
||||
'token' => ['required'],
|
||||
'email' => ['required', 'string', 'email'],
|
||||
'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()],
|
||||
]);
|
||||
|
||||
// Here we will attempt to reset the user's password. If it is successful we
|
||||
// will update the password on an actual user model and persist it to the
|
||||
// database. Otherwise we will parse the error and return the response.
|
||||
$status = Password::reset(
|
||||
$this->only('email', 'password', 'password_confirmation', 'token'),
|
||||
function ($user) {
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($this->password),
|
||||
'remember_token' => Str::random(60),
|
||||
])->save();
|
||||
|
||||
event(new PasswordReset($user));
|
||||
}
|
||||
);
|
||||
|
||||
// If the password was successfully reset, we will redirect the user back to
|
||||
// the application's home authenticated view. If there is an error we can
|
||||
// redirect them back to where they came from with their error message.
|
||||
if ($status != Password::PasswordReset) {
|
||||
$this->addError('email', __($status));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Session::flash('status', __($status));
|
||||
|
||||
$this->redirectRoute('login', navigate: true);
|
||||
}
|
||||
}
|
39
app/Livewire/Auth/VerifyEmail.php
Normal file
39
app/Livewire/Auth/VerifyEmail.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use App\Livewire\Actions\Logout;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth')]
|
||||
class VerifyEmail extends Component
|
||||
{
|
||||
/**
|
||||
* Send an email verification notification to the user.
|
||||
*/
|
||||
public function sendVerification(): void
|
||||
{
|
||||
if (Auth::user()->hasVerifiedEmail()) {
|
||||
$this->redirectIntended(default: route('dashboard', absolute: false), navigate: true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Auth::user()->sendEmailVerificationNotification();
|
||||
|
||||
Session::flash('status', 'verification-link-sent');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the current user out of the application.
|
||||
*/
|
||||
public function logout(Logout $logout): void
|
||||
{
|
||||
$logout();
|
||||
|
||||
$this->redirect('/', navigate: true);
|
||||
}
|
||||
}
|
10
app/Livewire/Settings/Appearance.php
Normal file
10
app/Livewire/Settings/Appearance.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Settings;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class Appearance extends Component
|
||||
{
|
||||
//
|
||||
}
|
26
app/Livewire/Settings/DeleteUserForm.php
Normal file
26
app/Livewire/Settings/DeleteUserForm.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Settings;
|
||||
|
||||
use App\Livewire\Actions\Logout;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Livewire\Component;
|
||||
|
||||
class DeleteUserForm extends Component
|
||||
{
|
||||
public string $password = '';
|
||||
|
||||
/**
|
||||
* Delete the currently authenticated user.
|
||||
*/
|
||||
public function deleteUser(Logout $logout): void
|
||||
{
|
||||
$this->validate([
|
||||
'password' => ['required', 'string', 'current_password'],
|
||||
]);
|
||||
|
||||
tap(Auth::user(), $logout(...))->delete();
|
||||
|
||||
$this->redirect('/', navigate: true);
|
||||
}
|
||||
}
|
43
app/Livewire/Settings/Password.php
Normal file
43
app/Livewire/Settings/Password.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Settings;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rules\Password as PasswordRule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Component;
|
||||
|
||||
class Password extends Component
|
||||
{
|
||||
public string $current_password = '';
|
||||
|
||||
public string $password = '';
|
||||
|
||||
public string $password_confirmation = '';
|
||||
|
||||
/**
|
||||
* Update the password for the currently authenticated user.
|
||||
*/
|
||||
public function updatePassword(): void
|
||||
{
|
||||
try {
|
||||
$validated = $this->validate([
|
||||
'current_password' => ['required', 'string', 'current_password'],
|
||||
'password' => ['required', 'string', PasswordRule::defaults(), 'confirmed'],
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
$this->reset('current_password', 'password', 'password_confirmation');
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
Auth::user()->update([
|
||||
'password' => Hash::make($validated['password']),
|
||||
]);
|
||||
|
||||
$this->reset('current_password', 'password', 'password_confirmation');
|
||||
|
||||
$this->dispatch('password-updated');
|
||||
}
|
||||
}
|
74
app/Livewire/Settings/Profile.php
Normal file
74
app/Livewire/Settings/Profile.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Settings;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Livewire\Component;
|
||||
|
||||
class Profile extends Component
|
||||
{
|
||||
public string $name = '';
|
||||
|
||||
public string $email = '';
|
||||
|
||||
/**
|
||||
* Mount the component.
|
||||
*/
|
||||
public function mount(): void
|
||||
{
|
||||
$this->name = Auth::user()->name;
|
||||
$this->email = Auth::user()->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the profile information for the currently authenticated user.
|
||||
*/
|
||||
public function updateProfileInformation(): void
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
$validated = $this->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
|
||||
'email' => [
|
||||
'required',
|
||||
'string',
|
||||
'lowercase',
|
||||
'email',
|
||||
'max:255',
|
||||
Rule::unique(User::class)->ignore($user->id),
|
||||
],
|
||||
]);
|
||||
|
||||
$user->fill($validated);
|
||||
|
||||
if ($user->isDirty('email')) {
|
||||
$user->email_verified_at = null;
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
$this->dispatch('profile-updated', name: $user->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email verification notification to the current user.
|
||||
*/
|
||||
public function resendVerificationNotification(): void
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user->hasVerifiedEmail()) {
|
||||
$this->redirectIntended(default: route('dashboard', absolute: false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$user->sendEmailVerificationNotification();
|
||||
|
||||
Session::flash('status', 'verification-link-sent');
|
||||
}
|
||||
}
|
23
app/Models/Application.php
Normal file
23
app/Models/Application.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Application extends Model
|
||||
{
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'message',
|
||||
];
|
||||
|
||||
public function uploads()
|
||||
{
|
||||
return $this->hasMany(Upload::class);
|
||||
}
|
||||
}
|
18
app/Models/Upload.php
Normal file
18
app/Models/Upload.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Upload extends Model
|
||||
{
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'application_id',
|
||||
'file_path',
|
||||
];
|
||||
}
|
60
app/Models/User.php
Normal file
60
app/Models/User.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's initials
|
||||
*/
|
||||
public function initials(): string
|
||||
{
|
||||
return Str::of($this->name)
|
||||
->explode(' ')
|
||||
->map(fn (string $name) => Str::of($name)->substr(0, 1))
|
||||
->implode('');
|
||||
}
|
||||
}
|
24
app/Providers/AppServiceProvider.php
Normal file
24
app/Providers/AppServiceProvider.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
18
artisan
Executable file
18
artisan
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Application;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
// Register the Composer autoloader...
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
// Bootstrap Laravel and handle the command...
|
||||
/** @var Application $app */
|
||||
$app = require_once __DIR__.'/bootstrap/app.php';
|
||||
|
||||
$status = $app->handleCommand(new ArgvInput);
|
||||
|
||||
exit($status);
|
18
bootstrap/app.php
Normal file
18
bootstrap/app.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
web: __DIR__.'/../routes/web.php',
|
||||
commands: __DIR__.'/../routes/console.php',
|
||||
health: '/up',
|
||||
)
|
||||
->withMiddleware(function (Middleware $middleware) {
|
||||
//
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
//
|
||||
})->create();
|
2
bootstrap/cache/.gitignore
vendored
Normal file
2
bootstrap/cache/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
6
bootstrap/providers.php
Normal file
6
bootstrap/providers.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
App\Providers\AppServiceProvider::class,
|
||||
Mews\Captcha\CaptchaServiceProvider::class,
|
||||
];
|
82
composer.json
Normal file
82
composer.json
Normal file
@ -0,0 +1,82 @@
|
||||
{
|
||||
"$schema": "https://getcomposer.org/schema.json",
|
||||
"name": "laravel/livewire-starter-kit",
|
||||
"type": "project",
|
||||
"description": "The official Laravel starter kit for Livewire.",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"framework"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"livewire/flux": "^2.1.1",
|
||||
"livewire/volt": "^1.7.0",
|
||||
"mews/captcha": "^3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
"laravel/pail": "^1.2.2",
|
||||
"laravel/pint": "^1.18",
|
||||
"laravel/sail": "^1.41",
|
||||
"mockery/mockery": "^1.6",
|
||||
"nunomaduro/collision": "^8.6",
|
||||
"pestphp/pest": "^3.8",
|
||||
"pestphp/pest-plugin-laravel": "^3.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "app/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||
],
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
],
|
||||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate --ansi",
|
||||
"@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
|
||||
"@php artisan migrate --graceful --ansi"
|
||||
],
|
||||
"dev": [
|
||||
"Composer\\Config::disableProcessTimeout",
|
||||
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
|
||||
],
|
||||
"test": [
|
||||
"@php artisan config:clear --ansi",
|
||||
"@php artisan test"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": []
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"pestphp/pest-plugin": true,
|
||||
"php-http/discovery": true
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
}
|
9446
composer.lock
generated
Normal file
9446
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
126
config/app.php
Normal file
126
config/app.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value is the name of your application, which will be used when the
|
||||
| framework needs to place the application's name in a notification or
|
||||
| other UI elements where an application name needs to be displayed.
|
||||
|
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Laravel'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Environment
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value determines the "environment" your application is currently
|
||||
| running in. This may determine how you prefer to configure various
|
||||
| services the application utilizes. Set this in your ".env" file.
|
||||
|
|
||||
*/
|
||||
|
||||
'env' => env('APP_ENV', 'production'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Debug Mode
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When your application is in debug mode, detailed error messages with
|
||||
| stack traces will be shown on every error that occurs within your
|
||||
| application. If disabled, a simple generic error page is shown.
|
||||
|
|
||||
*/
|
||||
|
||||
'debug' => (bool) env('APP_DEBUG', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application URL
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This URL is used by the console to properly generate URLs when using
|
||||
| the Artisan command line tool. You should set this to the root of
|
||||
| the application so that it's available within Artisan commands.
|
||||
|
|
||||
*/
|
||||
|
||||
'url' => env('APP_URL', 'http://localhost'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Timezone
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify the default timezone for your application, which
|
||||
| will be used by the PHP date and date-time functions. The timezone
|
||||
| is set to "UTC" by default as it is suitable for most use cases.
|
||||
|
|
||||
*/
|
||||
|
||||
'timezone' => 'UTC',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Locale Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The application locale determines the default locale that will be used
|
||||
| by Laravel's translation / localization methods. This option can be
|
||||
| set to any locale for which you plan to have translation strings.
|
||||
|
|
||||
*/
|
||||
|
||||
'locale' => env('APP_LOCALE', 'en'),
|
||||
|
||||
'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),
|
||||
|
||||
'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Encryption Key
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This key is utilized by Laravel's encryption services and should be set
|
||||
| to a random, 32 character string to ensure that all encrypted values
|
||||
| are secure. You should do this prior to deploying the application.
|
||||
|
|
||||
*/
|
||||
|
||||
'cipher' => 'AES-256-CBC',
|
||||
|
||||
'key' => env('APP_KEY'),
|
||||
|
||||
'previous_keys' => [
|
||||
...array_filter(
|
||||
explode(',', env('APP_PREVIOUS_KEYS', ''))
|
||||
),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Maintenance Mode Driver
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These configuration options determine the driver used to determine and
|
||||
| manage Laravel's "maintenance mode" status. The "cache" driver will
|
||||
| allow maintenance mode to be controlled across multiple machines.
|
||||
|
|
||||
| Supported drivers: "file", "cache"
|
||||
|
|
||||
*/
|
||||
|
||||
'maintenance' => [
|
||||
'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),
|
||||
'store' => env('APP_MAINTENANCE_STORE', 'database'),
|
||||
],
|
||||
|
||||
];
|
115
config/auth.php
Normal file
115
config/auth.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Defaults
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option defines the default authentication "guard" and password
|
||||
| reset "broker" for your application. You may change these values
|
||||
| as required, but they're a perfect start for most applications.
|
||||
|
|
||||
*/
|
||||
|
||||
'defaults' => [
|
||||
'guard' => env('AUTH_GUARD', 'web'),
|
||||
'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Guards
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Next, you may define every authentication guard for your application.
|
||||
| Of course, a great default configuration has been defined for you
|
||||
| which utilizes session storage plus the Eloquent user provider.
|
||||
|
|
||||
| All authentication guards have a user provider, which defines how the
|
||||
| users are actually retrieved out of your database or other storage
|
||||
| system used by the application. Typically, Eloquent is utilized.
|
||||
|
|
||||
| Supported: "session"
|
||||
|
|
||||
*/
|
||||
|
||||
'guards' => [
|
||||
'web' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'users',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| User Providers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| All authentication guards have a user provider, which defines how the
|
||||
| users are actually retrieved out of your database or other storage
|
||||
| system used by the application. Typically, Eloquent is utilized.
|
||||
|
|
||||
| If you have multiple user tables or models you may configure multiple
|
||||
| providers to represent the model / table. These providers may then
|
||||
| be assigned to any extra authentication guards you have defined.
|
||||
|
|
||||
| Supported: "database", "eloquent"
|
||||
|
|
||||
*/
|
||||
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => env('AUTH_MODEL', App\Models\User::class),
|
||||
],
|
||||
|
||||
// 'users' => [
|
||||
// 'driver' => 'database',
|
||||
// 'table' => 'users',
|
||||
// ],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Resetting Passwords
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These configuration options specify the behavior of Laravel's password
|
||||
| reset functionality, including the table utilized for token storage
|
||||
| and the user provider that is invoked to actually retrieve users.
|
||||
|
|
||||
| The expiry time is the number of minutes that each reset token will be
|
||||
| considered valid. This security feature keeps tokens short-lived so
|
||||
| they have less time to be guessed. You may change this as needed.
|
||||
|
|
||||
| The throttle setting is the number of seconds a user must wait before
|
||||
| generating more password reset tokens. This prevents the user from
|
||||
| quickly generating a very large amount of password reset tokens.
|
||||
|
|
||||
*/
|
||||
|
||||
'passwords' => [
|
||||
'users' => [
|
||||
'provider' => 'users',
|
||||
'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
|
||||
'expire' => 60,
|
||||
'throttle' => 60,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Confirmation Timeout
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define the amount of seconds before a password confirmation
|
||||
| window expires and users are asked to re-enter their password via the
|
||||
| confirmation screen. By default, the timeout lasts for three hours.
|
||||
|
|
||||
*/
|
||||
|
||||
'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800),
|
||||
|
||||
];
|
108
config/cache.php
Normal file
108
config/cache.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Cache Store
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default cache store that will be used by the
|
||||
| framework. This connection is utilized if another isn't explicitly
|
||||
| specified when running a cache operation inside the application.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('CACHE_STORE', 'database'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Stores
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define all of the cache "stores" for your application as
|
||||
| well as their drivers. You may even define multiple stores for the
|
||||
| same cache driver to group types of items stored in your caches.
|
||||
|
|
||||
| Supported drivers: "array", "database", "file", "memcached",
|
||||
| "redis", "dynamodb", "octane", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'stores' => [
|
||||
|
||||
'array' => [
|
||||
'driver' => 'array',
|
||||
'serialize' => false,
|
||||
],
|
||||
|
||||
'database' => [
|
||||
'driver' => 'database',
|
||||
'connection' => env('DB_CACHE_CONNECTION'),
|
||||
'table' => env('DB_CACHE_TABLE', 'cache'),
|
||||
'lock_connection' => env('DB_CACHE_LOCK_CONNECTION'),
|
||||
'lock_table' => env('DB_CACHE_LOCK_TABLE'),
|
||||
],
|
||||
|
||||
'file' => [
|
||||
'driver' => 'file',
|
||||
'path' => storage_path('framework/cache/data'),
|
||||
'lock_path' => storage_path('framework/cache/data'),
|
||||
],
|
||||
|
||||
'memcached' => [
|
||||
'driver' => 'memcached',
|
||||
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
|
||||
'sasl' => [
|
||||
env('MEMCACHED_USERNAME'),
|
||||
env('MEMCACHED_PASSWORD'),
|
||||
],
|
||||
'options' => [
|
||||
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
|
||||
],
|
||||
'servers' => [
|
||||
[
|
||||
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
|
||||
'port' => env('MEMCACHED_PORT', 11211),
|
||||
'weight' => 100,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'redis' => [
|
||||
'driver' => 'redis',
|
||||
'connection' => env('REDIS_CACHE_CONNECTION', 'cache'),
|
||||
'lock_connection' => env('REDIS_CACHE_LOCK_CONNECTION', 'default'),
|
||||
],
|
||||
|
||||
'dynamodb' => [
|
||||
'driver' => 'dynamodb',
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
|
||||
'endpoint' => env('DYNAMODB_ENDPOINT'),
|
||||
],
|
||||
|
||||
'octane' => [
|
||||
'driver' => 'octane',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Key Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When utilizing the APC, database, memcached, Redis, and DynamoDB cache
|
||||
| stores, there might be other applications using the same cache. For
|
||||
| that reason, you may prefix every cache key to avoid collisions.
|
||||
|
|
||||
*/
|
||||
|
||||
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'),
|
||||
|
||||
];
|
174
config/database.php
Normal file
174
config/database.php
Normal file
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Database Connection Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify which of the database connections below you wish
|
||||
| to use as your default connection for database operations. This is
|
||||
| the connection which will be utilized unless another connection
|
||||
| is explicitly specified when you execute a query / statement.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('DB_CONNECTION', 'sqlite'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Database Connections
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Below are all of the database connections defined for your application.
|
||||
| An example configuration is provided for each database system which
|
||||
| is supported by Laravel. You're free to add / remove connections.
|
||||
|
|
||||
*/
|
||||
|
||||
'connections' => [
|
||||
|
||||
'sqlite' => [
|
||||
'driver' => 'sqlite',
|
||||
'url' => env('DB_URL'),
|
||||
'database' => env('DB_DATABASE', database_path('database.sqlite')),
|
||||
'prefix' => '',
|
||||
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
|
||||
'busy_timeout' => null,
|
||||
'journal_mode' => null,
|
||||
'synchronous' => null,
|
||||
],
|
||||
|
||||
'mysql' => [
|
||||
'driver' => 'mysql',
|
||||
'url' => env('DB_URL'),
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '3306'),
|
||||
'database' => env('DB_DATABASE', 'laravel'),
|
||||
'username' => env('DB_USERNAME', 'root'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'unix_socket' => env('DB_SOCKET', ''),
|
||||
'charset' => env('DB_CHARSET', 'utf8mb4'),
|
||||
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'strict' => true,
|
||||
'engine' => null,
|
||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||
]) : [],
|
||||
],
|
||||
|
||||
'mariadb' => [
|
||||
'driver' => 'mariadb',
|
||||
'url' => env('DB_URL'),
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '3306'),
|
||||
'database' => env('DB_DATABASE', 'laravel'),
|
||||
'username' => env('DB_USERNAME', 'root'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'unix_socket' => env('DB_SOCKET', ''),
|
||||
'charset' => env('DB_CHARSET', 'utf8mb4'),
|
||||
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'strict' => true,
|
||||
'engine' => null,
|
||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||
]) : [],
|
||||
],
|
||||
|
||||
'pgsql' => [
|
||||
'driver' => 'pgsql',
|
||||
'url' => env('DB_URL'),
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '5432'),
|
||||
'database' => env('DB_DATABASE', 'laravel'),
|
||||
'username' => env('DB_USERNAME', 'root'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => env('DB_CHARSET', 'utf8'),
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'search_path' => 'public',
|
||||
'sslmode' => 'prefer',
|
||||
],
|
||||
|
||||
'sqlsrv' => [
|
||||
'driver' => 'sqlsrv',
|
||||
'url' => env('DB_URL'),
|
||||
'host' => env('DB_HOST', 'localhost'),
|
||||
'port' => env('DB_PORT', '1433'),
|
||||
'database' => env('DB_DATABASE', 'laravel'),
|
||||
'username' => env('DB_USERNAME', 'root'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => env('DB_CHARSET', 'utf8'),
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
// 'encrypt' => env('DB_ENCRYPT', 'yes'),
|
||||
// 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Migration Repository Table
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This table keeps track of all the migrations that have already run for
|
||||
| your application. Using this information, we can determine which of
|
||||
| the migrations on disk haven't actually been run on the database.
|
||||
|
|
||||
*/
|
||||
|
||||
'migrations' => [
|
||||
'table' => 'migrations',
|
||||
'update_date_on_publish' => true,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Redis Databases
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Redis is an open source, fast, and advanced key-value store that also
|
||||
| provides a richer body of commands than a typical key-value system
|
||||
| such as Memcached. You may define your connection settings here.
|
||||
|
|
||||
*/
|
||||
|
||||
'redis' => [
|
||||
|
||||
'client' => env('REDIS_CLIENT', 'phpredis'),
|
||||
|
||||
'options' => [
|
||||
'cluster' => env('REDIS_CLUSTER', 'redis'),
|
||||
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
|
||||
'persistent' => env('REDIS_PERSISTENT', false),
|
||||
],
|
||||
|
||||
'default' => [
|
||||
'url' => env('REDIS_URL'),
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'username' => env('REDIS_USERNAME'),
|
||||
'password' => env('REDIS_PASSWORD'),
|
||||
'port' => env('REDIS_PORT', '6379'),
|
||||
'database' => env('REDIS_DB', '0'),
|
||||
],
|
||||
|
||||
'cache' => [
|
||||
'url' => env('REDIS_URL'),
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'username' => env('REDIS_USERNAME'),
|
||||
'password' => env('REDIS_PASSWORD'),
|
||||
'port' => env('REDIS_PORT', '6379'),
|
||||
'database' => env('REDIS_CACHE_DB', '1'),
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
80
config/filesystems.php
Normal file
80
config/filesystems.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Filesystem Disk
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify the default filesystem disk that should be used
|
||||
| by the framework. The "local" disk, as well as a variety of cloud
|
||||
| based disks are available to your application for file storage.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('FILESYSTEM_DISK', 'local'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Filesystem Disks
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Below you may configure as many filesystem disks as necessary, and you
|
||||
| may even configure multiple disks for the same driver. Examples for
|
||||
| most supported storage drivers are configured here for reference.
|
||||
|
|
||||
| Supported drivers: "local", "ftp", "sftp", "s3"
|
||||
|
|
||||
*/
|
||||
|
||||
'disks' => [
|
||||
|
||||
'local' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/private'),
|
||||
'serve' => true,
|
||||
'throw' => false,
|
||||
'report' => false,
|
||||
],
|
||||
|
||||
'public' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/public'),
|
||||
'url' => env('APP_URL').'/storage',
|
||||
'visibility' => 'public',
|
||||
'throw' => false,
|
||||
'report' => false,
|
||||
],
|
||||
|
||||
's3' => [
|
||||
'driver' => 's3',
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION'),
|
||||
'bucket' => env('AWS_BUCKET'),
|
||||
'url' => env('AWS_URL'),
|
||||
'endpoint' => env('AWS_ENDPOINT'),
|
||||
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
|
||||
'throw' => false,
|
||||
'report' => false,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Symbolic Links
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may configure the symbolic links that will be created when the
|
||||
| `storage:link` Artisan command is executed. The array keys should be
|
||||
| the locations of the links and the values should be their targets.
|
||||
|
|
||||
*/
|
||||
|
||||
'links' => [
|
||||
public_path('storage') => storage_path('app/public'),
|
||||
],
|
||||
|
||||
];
|
132
config/logging.php
Normal file
132
config/logging.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
use Monolog\Handler\NullHandler;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Handler\SyslogUdpHandler;
|
||||
use Monolog\Processor\PsrLogMessageProcessor;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Log Channel
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option defines the default log channel that is utilized to write
|
||||
| messages to your logs. The value provided here should match one of
|
||||
| the channels present in the list of "channels" configured below.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('LOG_CHANNEL', 'stack'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Deprecations Log Channel
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the log channel that should be used to log warnings
|
||||
| regarding deprecated PHP and library features. This allows you to get
|
||||
| your application ready for upcoming major versions of dependencies.
|
||||
|
|
||||
*/
|
||||
|
||||
'deprecations' => [
|
||||
'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
|
||||
'trace' => env('LOG_DEPRECATIONS_TRACE', false),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Log Channels
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may configure the log channels for your application. Laravel
|
||||
| utilizes the Monolog PHP logging library, which includes a variety
|
||||
| of powerful log handlers and formatters that you're free to use.
|
||||
|
|
||||
| Available drivers: "single", "daily", "slack", "syslog",
|
||||
| "errorlog", "monolog", "custom", "stack"
|
||||
|
|
||||
*/
|
||||
|
||||
'channels' => [
|
||||
|
||||
'stack' => [
|
||||
'driver' => 'stack',
|
||||
'channels' => explode(',', env('LOG_STACK', 'single')),
|
||||
'ignore_exceptions' => false,
|
||||
],
|
||||
|
||||
'single' => [
|
||||
'driver' => 'single',
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'replace_placeholders' => true,
|
||||
],
|
||||
|
||||
'daily' => [
|
||||
'driver' => 'daily',
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'days' => env('LOG_DAILY_DAYS', 14),
|
||||
'replace_placeholders' => true,
|
||||
],
|
||||
|
||||
'slack' => [
|
||||
'driver' => 'slack',
|
||||
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||
'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'),
|
||||
'emoji' => env('LOG_SLACK_EMOJI', ':boom:'),
|
||||
'level' => env('LOG_LEVEL', 'critical'),
|
||||
'replace_placeholders' => true,
|
||||
],
|
||||
|
||||
'papertrail' => [
|
||||
'driver' => 'monolog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
|
||||
'handler_with' => [
|
||||
'host' => env('PAPERTRAIL_URL'),
|
||||
'port' => env('PAPERTRAIL_PORT'),
|
||||
'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),
|
||||
],
|
||||
'processors' => [PsrLogMessageProcessor::class],
|
||||
],
|
||||
|
||||
'stderr' => [
|
||||
'driver' => 'monolog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'handler' => StreamHandler::class,
|
||||
'formatter' => env('LOG_STDERR_FORMATTER'),
|
||||
'with' => [
|
||||
'stream' => 'php://stderr',
|
||||
],
|
||||
'processors' => [PsrLogMessageProcessor::class],
|
||||
],
|
||||
|
||||
'syslog' => [
|
||||
'driver' => 'syslog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER),
|
||||
'replace_placeholders' => true,
|
||||
],
|
||||
|
||||
'errorlog' => [
|
||||
'driver' => 'errorlog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'replace_placeholders' => true,
|
||||
],
|
||||
|
||||
'null' => [
|
||||
'driver' => 'monolog',
|
||||
'handler' => NullHandler::class,
|
||||
],
|
||||
|
||||
'emergency' => [
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
116
config/mail.php
Normal file
116
config/mail.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Mailer
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default mailer that is used to send all email
|
||||
| messages unless another mailer is explicitly specified when sending
|
||||
| the message. All additional mailers can be configured within the
|
||||
| "mailers" array. Examples of each type of mailer are provided.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('MAIL_MAILER', 'log'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Mailer Configurations
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may configure all of the mailers used by your application plus
|
||||
| their respective settings. Several examples have been configured for
|
||||
| you and you are free to add your own as your application requires.
|
||||
|
|
||||
| Laravel supports a variety of mail "transport" drivers that can be used
|
||||
| when delivering an email. You may specify which one you're using for
|
||||
| your mailers below. You may also add additional mailers if needed.
|
||||
|
|
||||
| Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2",
|
||||
| "postmark", "resend", "log", "array",
|
||||
| "failover", "roundrobin"
|
||||
|
|
||||
*/
|
||||
|
||||
'mailers' => [
|
||||
|
||||
'smtp' => [
|
||||
'transport' => 'smtp',
|
||||
'scheme' => env('MAIL_SCHEME'),
|
||||
'url' => env('MAIL_URL'),
|
||||
'host' => env('MAIL_HOST', '127.0.0.1'),
|
||||
'port' => env('MAIL_PORT', 2525),
|
||||
'username' => env('MAIL_USERNAME'),
|
||||
'password' => env('MAIL_PASSWORD'),
|
||||
'timeout' => null,
|
||||
'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url(env('APP_URL', 'http://localhost'), PHP_URL_HOST)),
|
||||
],
|
||||
|
||||
'ses' => [
|
||||
'transport' => 'ses',
|
||||
],
|
||||
|
||||
'postmark' => [
|
||||
'transport' => 'postmark',
|
||||
// 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'),
|
||||
// 'client' => [
|
||||
// 'timeout' => 5,
|
||||
// ],
|
||||
],
|
||||
|
||||
'resend' => [
|
||||
'transport' => 'resend',
|
||||
],
|
||||
|
||||
'sendmail' => [
|
||||
'transport' => 'sendmail',
|
||||
'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'),
|
||||
],
|
||||
|
||||
'log' => [
|
||||
'transport' => 'log',
|
||||
'channel' => env('MAIL_LOG_CHANNEL'),
|
||||
],
|
||||
|
||||
'array' => [
|
||||
'transport' => 'array',
|
||||
],
|
||||
|
||||
'failover' => [
|
||||
'transport' => 'failover',
|
||||
'mailers' => [
|
||||
'smtp',
|
||||
'log',
|
||||
],
|
||||
],
|
||||
|
||||
'roundrobin' => [
|
||||
'transport' => 'roundrobin',
|
||||
'mailers' => [
|
||||
'ses',
|
||||
'postmark',
|
||||
],
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Global "From" Address
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| You may wish for all emails sent by your application to be sent from
|
||||
| the same address. Here you may specify a name and address that is
|
||||
| used globally for all emails that are sent by your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'from' => [
|
||||
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
|
||||
'name' => env('MAIL_FROM_NAME', 'Example'),
|
||||
],
|
||||
|
||||
];
|
112
config/queue.php
Normal file
112
config/queue.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Queue Connection Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Laravel's queue supports a variety of backends via a single, unified
|
||||
| API, giving you convenient access to each backend using identical
|
||||
| syntax for each. The default queue connection is defined below.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('QUEUE_CONNECTION', 'database'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Queue Connections
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may configure the connection options for every queue backend
|
||||
| used by your application. An example configuration is provided for
|
||||
| each backend supported by Laravel. You're also free to add more.
|
||||
|
|
||||
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'connections' => [
|
||||
|
||||
'sync' => [
|
||||
'driver' => 'sync',
|
||||
],
|
||||
|
||||
'database' => [
|
||||
'driver' => 'database',
|
||||
'connection' => env('DB_QUEUE_CONNECTION'),
|
||||
'table' => env('DB_QUEUE_TABLE', 'jobs'),
|
||||
'queue' => env('DB_QUEUE', 'default'),
|
||||
'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90),
|
||||
'after_commit' => false,
|
||||
],
|
||||
|
||||
'beanstalkd' => [
|
||||
'driver' => 'beanstalkd',
|
||||
'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'),
|
||||
'queue' => env('BEANSTALKD_QUEUE', 'default'),
|
||||
'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90),
|
||||
'block_for' => 0,
|
||||
'after_commit' => false,
|
||||
],
|
||||
|
||||
'sqs' => [
|
||||
'driver' => 'sqs',
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
|
||||
'queue' => env('SQS_QUEUE', 'default'),
|
||||
'suffix' => env('SQS_SUFFIX'),
|
||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
'after_commit' => false,
|
||||
],
|
||||
|
||||
'redis' => [
|
||||
'driver' => 'redis',
|
||||
'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
|
||||
'queue' => env('REDIS_QUEUE', 'default'),
|
||||
'retry_after' => (int) env('REDIS_QUEUE_RETRY_AFTER', 90),
|
||||
'block_for' => null,
|
||||
'after_commit' => false,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Job Batching
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following options configure the database and table that store job
|
||||
| batching information. These options can be updated to any database
|
||||
| connection and table which has been defined by your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'batching' => [
|
||||
'database' => env('DB_CONNECTION', 'sqlite'),
|
||||
'table' => 'job_batches',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Failed Queue Jobs
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These options configure the behavior of failed queue job logging so you
|
||||
| can control how and where failed jobs are stored. Laravel ships with
|
||||
| support for storing failed jobs in a simple file or in a database.
|
||||
|
|
||||
| Supported drivers: "database-uuids", "dynamodb", "file", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => [
|
||||
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
|
||||
'database' => env('DB_CONNECTION', 'sqlite'),
|
||||
'table' => 'failed_jobs',
|
||||
],
|
||||
|
||||
];
|
38
config/services.php
Normal file
38
config/services.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Third Party Services
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This file is for storing the credentials for third party services such
|
||||
| as Mailgun, Postmark, AWS and more. This file provides the de facto
|
||||
| location for this type of information, allowing packages to have
|
||||
| a conventional file to locate the various service credentials.
|
||||
|
|
||||
*/
|
||||
|
||||
'postmark' => [
|
||||
'token' => env('POSTMARK_TOKEN'),
|
||||
],
|
||||
|
||||
'ses' => [
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
],
|
||||
|
||||
'resend' => [
|
||||
'key' => env('RESEND_KEY'),
|
||||
],
|
||||
|
||||
'slack' => [
|
||||
'notifications' => [
|
||||
'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'),
|
||||
'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
|
||||
],
|
||||
],
|
||||
|
||||
];
|
217
config/session.php
Normal file
217
config/session.php
Normal file
@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Session Driver
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option determines the default session driver that is utilized for
|
||||
| incoming requests. Laravel supports a variety of storage options to
|
||||
| persist session data. Database storage is a great default choice.
|
||||
|
|
||||
| Supported: "file", "cookie", "database", "apc",
|
||||
| "memcached", "redis", "dynamodb", "array"
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => env('SESSION_DRIVER', 'database'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Lifetime
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify the number of minutes that you wish the session
|
||||
| to be allowed to remain idle before it expires. If you want them
|
||||
| to expire immediately when the browser is closed then you may
|
||||
| indicate that via the expire_on_close configuration option.
|
||||
|
|
||||
*/
|
||||
|
||||
'lifetime' => (int) env('SESSION_LIFETIME', 120),
|
||||
|
||||
'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Encryption
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option allows you to easily specify that all of your session data
|
||||
| should be encrypted before it's stored. All encryption is performed
|
||||
| automatically by Laravel and you may use the session like normal.
|
||||
|
|
||||
*/
|
||||
|
||||
'encrypt' => env('SESSION_ENCRYPT', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session File Location
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When utilizing the "file" session driver, the session files are placed
|
||||
| on disk. The default storage location is defined here; however, you
|
||||
| are free to provide another location where they should be stored.
|
||||
|
|
||||
*/
|
||||
|
||||
'files' => storage_path('framework/sessions'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Database Connection
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When using the "database" or "redis" session drivers, you may specify a
|
||||
| connection that should be used to manage these sessions. This should
|
||||
| correspond to a connection in your database configuration options.
|
||||
|
|
||||
*/
|
||||
|
||||
'connection' => env('SESSION_CONNECTION'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Database Table
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When using the "database" session driver, you may specify the table to
|
||||
| be used to store sessions. Of course, a sensible default is defined
|
||||
| for you; however, you're welcome to change this to another table.
|
||||
|
|
||||
*/
|
||||
|
||||
'table' => env('SESSION_TABLE', 'sessions'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Cache Store
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When using one of the framework's cache driven session backends, you may
|
||||
| define the cache store which should be used to store the session data
|
||||
| between requests. This must match one of your defined cache stores.
|
||||
|
|
||||
| Affects: "apc", "dynamodb", "memcached", "redis"
|
||||
|
|
||||
*/
|
||||
|
||||
'store' => env('SESSION_STORE'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Sweeping Lottery
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Some session drivers must manually sweep their storage location to get
|
||||
| rid of old sessions from storage. Here are the chances that it will
|
||||
| happen on a given request. By default, the odds are 2 out of 100.
|
||||
|
|
||||
*/
|
||||
|
||||
'lottery' => [2, 100],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Cookie Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may change the name of the session cookie that is created by
|
||||
| the framework. Typically, you should not need to change this value
|
||||
| since doing so does not grant a meaningful security improvement.
|
||||
|
|
||||
*/
|
||||
|
||||
'cookie' => env(
|
||||
'SESSION_COOKIE',
|
||||
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
|
||||
),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Cookie Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The session cookie path determines the path for which the cookie will
|
||||
| be regarded as available. Typically, this will be the root path of
|
||||
| your application, but you're free to change this when necessary.
|
||||
|
|
||||
*/
|
||||
|
||||
'path' => env('SESSION_PATH', '/'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Cookie Domain
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value determines the domain and subdomains the session cookie is
|
||||
| available to. By default, the cookie will be available to the root
|
||||
| domain and all subdomains. Typically, this shouldn't be changed.
|
||||
|
|
||||
*/
|
||||
|
||||
'domain' => env('SESSION_DOMAIN'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| HTTPS Only Cookies
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| By setting this option to true, session cookies will only be sent back
|
||||
| to the server if the browser has a HTTPS connection. This will keep
|
||||
| the cookie from being sent to you when it can't be done securely.
|
||||
|
|
||||
*/
|
||||
|
||||
'secure' => env('SESSION_SECURE_COOKIE'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| HTTP Access Only
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Setting this value to true will prevent JavaScript from accessing the
|
||||
| value of the cookie and the cookie will only be accessible through
|
||||
| the HTTP protocol. It's unlikely you should disable this option.
|
||||
|
|
||||
*/
|
||||
|
||||
'http_only' => env('SESSION_HTTP_ONLY', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Same-Site Cookies
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option determines how your cookies behave when cross-site requests
|
||||
| take place, and can be used to mitigate CSRF attacks. By default, we
|
||||
| will set this value to "lax" to permit secure cross-site requests.
|
||||
|
|
||||
| See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value
|
||||
|
|
||||
| Supported: "lax", "strict", "none", null
|
||||
|
|
||||
*/
|
||||
|
||||
'same_site' => env('SESSION_SAME_SITE', 'lax'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Partitioned Cookies
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Setting this value to true will tie the cookie to the top-level site for
|
||||
| a cross-site context. Partitioned cookies are accepted by the browser
|
||||
| when flagged "secure" and the Same-Site attribute is set to "none".
|
||||
|
|
||||
*/
|
||||
|
||||
'partitioned' => env('SESSION_PARTITIONED_COOKIE', false),
|
||||
|
||||
];
|
1
database/.gitignore
vendored
Normal file
1
database/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.sqlite*
|
44
database/factories/UserFactory.php
Normal file
44
database/factories/UserFactory.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
||||
*/
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The current password being used by the factory.
|
||||
*/
|
||||
protected static ?string $password;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->name(),
|
||||
'email' => fake()->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the model's email address should be unverified.
|
||||
*/
|
||||
public function unverified(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'email_verified_at' => null,
|
||||
]);
|
||||
}
|
||||
}
|
49
database/migrations/0001_01_01_000000_create_users_table.php
Normal file
49
database/migrations/0001_01_01_000000_create_users_table.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('password_reset_tokens', function (Blueprint $table) {
|
||||
$table->string('email')->primary();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('sessions', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->foreignId('user_id')->nullable()->index();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->longText('payload');
|
||||
$table->integer('last_activity')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
Schema::dropIfExists('password_reset_tokens');
|
||||
Schema::dropIfExists('sessions');
|
||||
}
|
||||
};
|
35
database/migrations/0001_01_01_000001_create_cache_table.php
Normal file
35
database/migrations/0001_01_01_000001_create_cache_table.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('cache', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->mediumText('value');
|
||||
$table->integer('expiration');
|
||||
});
|
||||
|
||||
Schema::create('cache_locks', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->string('owner');
|
||||
$table->integer('expiration');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('cache');
|
||||
Schema::dropIfExists('cache_locks');
|
||||
}
|
||||
};
|
57
database/migrations/0001_01_01_000002_create_jobs_table.php
Normal file
57
database/migrations/0001_01_01_000002_create_jobs_table.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
|
||||
Schema::create('job_batches', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->string('name');
|
||||
$table->integer('total_jobs');
|
||||
$table->integer('pending_jobs');
|
||||
$table->integer('failed_jobs');
|
||||
$table->longText('failed_job_ids');
|
||||
$table->mediumText('options')->nullable();
|
||||
$table->integer('cancelled_at')->nullable();
|
||||
$table->integer('created_at');
|
||||
$table->integer('finished_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
Schema::dropIfExists('job_batches');
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('applications', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid');
|
||||
$table->tinyInteger('status')->default(0);
|
||||
$table->string('message');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('applications');
|
||||
}
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('uploads', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('application_id')->constrained()->cascadeOnDelete();
|
||||
$table->string('file_path');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('uploads');
|
||||
}
|
||||
};
|
23
database/seeders/DatabaseSeeder.php
Normal file
23
database/seeders/DatabaseSeeder.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// User::factory(10)->create();
|
||||
|
||||
User::factory()->create([
|
||||
'name' => 'Test User',
|
||||
'email' => 'test@example.com',
|
||||
]);
|
||||
}
|
||||
}
|
2194
package-lock.json
generated
Normal file
2194
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
package.json
Normal file
22
package.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"dev": "vite"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.0.7",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.7.4",
|
||||
"concurrently": "^9.0.1",
|
||||
"laravel-vite-plugin": "^1.0",
|
||||
"tailwindcss": "^4.0.7",
|
||||
"vite": "^6.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-linux-x64-gnu": "4.9.5",
|
||||
"@tailwindcss/oxide-linux-x64-gnu": "^4.0.1",
|
||||
"lightningcss-linux-x64-gnu": "^1.29.1"
|
||||
}
|
||||
}
|
33
phpunit.xml
Normal file
33
phpunit.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Unit">
|
||||
<directory>tests/Unit</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Feature">
|
||||
<directory>tests/Feature</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<source>
|
||||
<include>
|
||||
<directory>app</directory>
|
||||
</include>
|
||||
</source>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
|
||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||
<env name="CACHE_STORE" value="array"/>
|
||||
<env name="DB_CONNECTION" value="sqlite"/>
|
||||
<env name="DB_DATABASE" value=":memory:"/>
|
||||
<env name="MAIL_MAILER" value="array"/>
|
||||
<env name="PULSE_ENABLED" value="false"/>
|
||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="TELESCOPE_ENABLED" value="false"/>
|
||||
</php>
|
||||
</phpunit>
|
25
public/.htaccess
Normal file
25
public/.htaccess
Normal file
@ -0,0 +1,25 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
<IfModule mod_negotiation.c>
|
||||
Options -MultiViews -Indexes
|
||||
</IfModule>
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
# Handle Authorization Header
|
||||
RewriteCond %{HTTP:Authorization} .
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
|
||||
# Handle X-XSRF-Token Header
|
||||
RewriteCond %{HTTP:x-xsrf-token} .
|
||||
RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}]
|
||||
|
||||
# Redirect Trailing Slashes If Not A Folder...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} (.+)/$
|
||||
RewriteRule ^ %1 [L,R=301]
|
||||
|
||||
# Send Requests To Front Controller...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [L]
|
||||
</IfModule>
|
BIN
public/apple-touch-icon.png
Normal file
BIN
public/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
3
public/favicon.svg
Normal file
3
public/favicon.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M175.706 42.0288C175.77 42.2647 175.802 42.5079 175.803 42.7522V80.7322C175.803 81.2197 175.674 81.6986 175.43 82.1204C175.186 82.5422 174.835 82.892 174.412 83.1346L142.549 101.488V137.865C142.549 138.855 142.023 139.769 141.165 140.267L74.6532 178.573C74.501 178.659 74.3349 178.715 74.1688 178.773C74.1065 178.794 74.0477 178.832 73.982 178.85C73.517 178.972 73.0283 178.972 72.5634 178.85C72.4872 178.829 72.418 178.787 72.3454 178.76C72.1931 178.704 72.034 178.656 71.8887 178.573L5.39092 140.267C4.96848 140.024 4.61747 139.675 4.37328 139.253C4.12909 138.831 4.00033 138.352 4 137.865V23.9249C4 23.6757 4.0346 23.4334 4.09688 23.198C4.11764 23.1184 4.16608 23.0457 4.19376 22.9661C4.24566 22.8207 4.2941 22.6719 4.37022 22.5369C4.42212 22.4469 4.49824 22.3742 4.56052 22.2911C4.6401 22.1803 4.71276 22.0661 4.80618 21.9692C4.88576 21.8896 4.98956 21.8307 5.07952 21.7615C5.17986 21.6784 5.26982 21.5884 5.384 21.5226L38.6381 2.36994C39.0591 2.12756 39.5363 2 40.0221 2C40.5078 2 40.985 2.12756 41.4061 2.36994L74.6567 21.5226H74.6636C74.7743 21.5919 74.8677 21.6784 74.9681 21.758C75.058 21.8272 75.1584 21.8896 75.2379 21.9657C75.3348 22.0661 75.404 22.1803 75.4871 22.2911C75.5459 22.3742 75.6255 22.4469 75.6739 22.5369C75.7535 22.6753 75.7985 22.8207 75.8538 22.9661C75.8815 23.0457 75.9299 23.1184 75.9507 23.2015C76.0144 23.4374 76.047 23.6806 76.0476 23.9249V95.0907L103.755 79.1296V42.7488C103.755 42.5065 103.79 42.2607 103.852 42.0288C103.876 41.9457 103.921 41.873 103.949 41.7934C104.004 41.648 104.053 41.4992 104.129 41.3642C104.181 41.2742 104.257 41.2015 104.316 41.1184C104.399 41.0076 104.468 40.8934 104.565 40.7965C104.644 40.7169 104.745 40.658 104.835 40.5888C104.939 40.5057 105.029 40.4157 105.139 40.3499L138.397 21.1972C138.818 20.9545 139.295 20.8268 139.781 20.8268C140.267 20.8268 140.744 20.9545 141.165 21.1972L174.415 40.3499C174.533 40.4192 174.623 40.5057 174.727 40.5853C174.813 40.6546 174.914 40.7169 174.993 40.793C175.09 40.8934 175.159 41.0076 175.242 41.1184C175.305 41.2015 175.381 41.2742 175.429 41.3642C175.509 41.4992 175.554 41.648 175.609 41.7934C175.64 41.873 175.685 41.9457 175.706 42.0288ZM170.26 79.1296V47.5465L158.624 54.248L142.549 63.5076V95.0907L170.263 79.1296H170.26ZM137.009 136.262V104.658L121.197 113.693L76.0441 139.475V171.376L137.009 136.262ZM9.54292 28.7192V136.262L70.5012 171.373V139.478L38.6554 121.447L38.645 121.44L38.6311 121.433C38.5239 121.371 38.4339 121.281 38.3336 121.205C38.2471 121.135 38.1467 121.08 38.0706 121.004L38.0637 120.993C37.9737 120.907 37.9115 120.8 37.8353 120.703C37.7661 120.609 37.6831 120.53 37.6277 120.433L37.6243 120.422C37.562 120.318 37.5239 120.194 37.479 120.076C37.434 119.972 37.3752 119.875 37.3475 119.765C37.3129 119.633 37.306 119.491 37.2921 119.356C37.2783 119.252 37.2506 119.148 37.2506 119.045V119.038V44.6803L21.1789 35.4172L9.54292 28.7192ZM40.0255 7.97071L12.3213 23.9249L40.0186 39.8792L67.7194 23.9215L40.0186 7.97071H40.0255ZM54.433 107.538L70.5047 98.2822V28.7192L58.8687 35.4207L42.7935 44.6803V114.243L54.433 107.538ZM139.781 26.798L112.08 42.7522L139.781 58.7065L167.478 42.7488L139.781 26.798ZM137.009 63.5076L120.934 54.248L109.298 47.5465V79.1296L125.37 88.3857L137.009 95.0907V63.5076ZM73.2692 134.68L113.9 111.474L134.21 99.878L106.53 83.9342L74.6601 102.291L45.6134 119.02L73.2692 134.68Z" fill="#E673A3"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
20
public/index.php
Normal file
20
public/index.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
// Determine if the application is in maintenance mode...
|
||||
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
|
||||
require $maintenance;
|
||||
}
|
||||
|
||||
// Register the Composer autoloader...
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
// Bootstrap Laravel and handle the request...
|
||||
/** @var Application $app */
|
||||
$app = require_once __DIR__.'/../bootstrap/app.php';
|
||||
|
||||
$app->handleRequest(Request::capture());
|
2
public/robots.txt
Normal file
2
public/robots.txt
Normal file
@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow:
|
66
resources/css/app.css
Normal file
66
resources/css/app.css
Normal file
@ -0,0 +1,66 @@
|
||||
@import 'tailwindcss';
|
||||
@import '../../vendor/livewire/flux/dist/flux.css';
|
||||
|
||||
@source '../views';
|
||||
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
|
||||
@source '../../vendor/livewire/flux-pro/stubs/**/*.blade.php';
|
||||
@source '../../vendor/livewire/flux/stubs/**/*.blade.php';
|
||||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@theme {
|
||||
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
|
||||
--color-zinc-50: #fafafa;
|
||||
--color-zinc-100: #f5f5f5;
|
||||
--color-zinc-200: #e5e5e5;
|
||||
--color-zinc-300: #d4d4d4;
|
||||
--color-zinc-400: #a3a3a3;
|
||||
--color-zinc-500: #737373;
|
||||
--color-zinc-600: #525252;
|
||||
--color-zinc-700: #404040;
|
||||
--color-zinc-800: #262626;
|
||||
--color-zinc-900: #171717;
|
||||
--color-zinc-950: #0a0a0a;
|
||||
|
||||
--color-accent: var(--color-neutral-800);
|
||||
--color-accent-content: var(--color-neutral-800);
|
||||
--color-accent-foreground: var(--color-white);
|
||||
}
|
||||
|
||||
@layer theme {
|
||||
.dark {
|
||||
--color-accent: var(--color-white);
|
||||
--color-accent-content: var(--color-white);
|
||||
--color-accent-foreground: var(--color-neutral-800);
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentColor);
|
||||
}
|
||||
}
|
||||
|
||||
[data-flux-field]:not(ui-radio, ui-checkbox) {
|
||||
@apply grid gap-2;
|
||||
}
|
||||
|
||||
[data-flux-label] {
|
||||
@apply !mb-0 !leading-tight;
|
||||
}
|
||||
|
||||
input:focus[data-flux-control],
|
||||
textarea:focus[data-flux-control],
|
||||
select:focus[data-flux-control] {
|
||||
@apply outline-hidden ring-2 ring-accent ring-offset-2 ring-offset-accent-foreground;
|
||||
}
|
||||
|
||||
/* \[:where(&)\]:size-4 {
|
||||
@apply size-4;
|
||||
} */
|
0
resources/js/app.js
Normal file
0
resources/js/app.js
Normal file
29
resources/views/application-status.blade.php
Normal file
29
resources/views/application-status.blade.php
Normal file
@ -0,0 +1,29 @@
|
||||
<x-layouts.guest :title="__('Application Status')">
|
||||
<div class="max-w-2xl mx-auto mt-10">
|
||||
<div class="p-5 mb-4 dark:bg-pink-950/50 rounded-lg">
|
||||
<flux:heading size="xl">Application Status</flux:heading>
|
||||
@php
|
||||
$status = [
|
||||
0 => 'Pending Review',
|
||||
1 => 'Approved',
|
||||
2 => 'Denied',
|
||||
];
|
||||
@endphp
|
||||
<flux:text class="mt-2 text-lg">
|
||||
<p><strong>Status:</strong> {{ $status[$application->status] }}</p>
|
||||
<p><strong>Created:</strong>
|
||||
{{ Carbon\Carbon::parse($application->created_at)->diffForHumans(['parts' => 2]) }}</p>
|
||||
</flux:text>
|
||||
</div>
|
||||
|
||||
<h2 class="mt-4 font-semibold">Uploaded Files:</h2>
|
||||
<div class="flex flex-wrap gap-4 mt-4">
|
||||
@foreach ($application->uploads as $upload)
|
||||
<div>
|
||||
<img class="h-48 w-fit object-cover rounded-2xl hover:-translate-y-1 hover:scale-110 transition duration-300 ease-in-out"
|
||||
src="{{ asset('storage/' . $upload->file_path) }}">
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts.guest>
|
14
resources/views/components/action-message.blade.php
Normal file
14
resources/views/components/action-message.blade.php
Normal file
@ -0,0 +1,14 @@
|
||||
@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']) }}
|
||||
>
|
||||
{{ $slot->isEmpty() ? __('Saved.') : $slot }}
|
||||
</div>
|
8
resources/views/components/app-logo-icon.blade.php
Normal file
8
resources/views/components/app-logo-icon.blade.php
Normal file
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 42" {{ $attributes }}>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M17.2 5.633 8.6.855 0 5.633v26.51l16.2 9 16.2-9v-8.442l7.6-4.223V9.856l-8.6-4.777-8.6 4.777V18.3l-5.6 3.111V5.633ZM38 18.301l-5.6 3.11v-6.157l5.6-3.11V18.3Zm-1.06-7.856-5.54 3.078-5.54-3.079 5.54-3.078 5.54 3.079ZM24.8 18.3v-6.157l5.6 3.111v6.158L24.8 18.3Zm-1 1.732 5.54 3.078-13.14 7.302-5.54-3.078 13.14-7.3v-.002Zm-16.2 7.89 7.6 4.222V38.3L2 30.966V7.92l5.6 3.111v16.892ZM8.6 9.3 3.06 6.222 8.6 3.143l5.54 3.08L8.6 9.3Zm21.8 15.51-13.2 7.334V38.3l13.2-7.334v-6.156ZM9.6 11.034l5.6-3.11v14.6l-5.6 3.11v-14.6Z"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 714 B |
6
resources/views/components/app-logo.blade.php
Normal file
6
resources/views/components/app-logo.blade.php
Normal file
@ -0,0 +1,6 @@
|
||||
<div class="flex aspect-square size-8 items-center justify-center rounded-md bg-accent-content text-accent-foreground">
|
||||
<x-app-logo-icon class="size-5 fill-current text-white dark:text-black" />
|
||||
</div>
|
||||
<div class="ms-1 grid flex-1 text-start text-sm">
|
||||
<span class="mb-0.5 truncate leading-none font-semibold">Laravel Starter Kit</span>
|
||||
</div>
|
9
resources/views/components/auth-header.blade.php
Normal file
9
resources/views/components/auth-header.blade.php
Normal file
@ -0,0 +1,9 @@
|
||||
@props([
|
||||
'title',
|
||||
'description',
|
||||
])
|
||||
|
||||
<div class="flex w-full flex-col text-center">
|
||||
<flux:heading size="xl">{{ $title }}</flux:heading>
|
||||
<flux:subheading>{{ $description }}</flux:subheading>
|
||||
</div>
|
9
resources/views/components/auth-session-status.blade.php
Normal file
9
resources/views/components/auth-session-status.blade.php
Normal file
@ -0,0 +1,9 @@
|
||||
@props([
|
||||
'status',
|
||||
])
|
||||
|
||||
@if ($status)
|
||||
<div {{ $attributes->merge(['class' => 'font-medium text-sm text-green-600']) }}>
|
||||
{{ $status }}
|
||||
</div>
|
||||
@endif
|
5
resources/views/components/layouts/app.blade.php
Normal file
5
resources/views/components/layouts/app.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
<x-layouts.app.sidebar :title="$title ?? null">
|
||||
<flux:main>
|
||||
{{ $slot }}
|
||||
</flux:main>
|
||||
</x-layouts.app.sidebar>
|
124
resources/views/components/layouts/app/header.blade.php
Normal file
124
resources/views/components/layouts/app/header.blade.php
Normal file
@ -0,0 +1,124 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||
<head>
|
||||
@include('partials.head')
|
||||
</head>
|
||||
<body class="min-h-screen bg-white dark:bg-zinc-800">
|
||||
<flux:header container class="border-b border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left" />
|
||||
|
||||
<a href="{{ route('dashboard') }}" class="ms-2 me-5 flex items-center space-x-2 rtl:space-x-reverse lg:ms-0" wire:navigate>
|
||||
<x-app-logo />
|
||||
</a>
|
||||
|
||||
<flux:navbar class="-mb-px max-lg:hidden">
|
||||
<flux:navbar.item icon="layout-grid" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>
|
||||
{{ __('Dashboard') }}
|
||||
</flux:navbar.item>
|
||||
</flux:navbar>
|
||||
|
||||
<flux:spacer />
|
||||
|
||||
<flux:navbar class="me-1.5 space-x-0.5 rtl:space-x-reverse py-0!">
|
||||
<flux:tooltip :content="__('Search')" position="bottom">
|
||||
<flux:navbar.item class="!h-10 [&>div>svg]:size-5" icon="magnifying-glass" href="#" :label="__('Search')" />
|
||||
</flux:tooltip>
|
||||
<flux:tooltip :content="__('Repository')" position="bottom">
|
||||
<flux:navbar.item
|
||||
class="h-10 max-lg:hidden [&>div>svg]:size-5"
|
||||
icon="folder-git-2"
|
||||
href="https://github.com/laravel/livewire-starter-kit"
|
||||
target="_blank"
|
||||
:label="__('Repository')"
|
||||
/>
|
||||
</flux:tooltip>
|
||||
<flux:tooltip :content="__('Documentation')" position="bottom">
|
||||
<flux:navbar.item
|
||||
class="h-10 max-lg:hidden [&>div>svg]:size-5"
|
||||
icon="book-open-text"
|
||||
href="https://laravel.com/docs/starter-kits#livewire"
|
||||
target="_blank"
|
||||
label="Documentation"
|
||||
/>
|
||||
</flux:tooltip>
|
||||
</flux:navbar>
|
||||
|
||||
<!-- Desktop User Menu -->
|
||||
<flux:dropdown position="top" align="end">
|
||||
<flux:profile
|
||||
class="cursor-pointer"
|
||||
:initials="auth()->user()->initials()"
|
||||
/>
|
||||
|
||||
<flux:menu>
|
||||
<flux:menu.radio.group>
|
||||
<div class="p-0 text-sm font-normal">
|
||||
<div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm">
|
||||
<span class="relative flex h-8 w-8 shrink-0 overflow-hidden rounded-lg">
|
||||
<span
|
||||
class="flex h-full w-full items-center justify-center rounded-lg bg-neutral-200 text-black dark:bg-neutral-700 dark:text-white"
|
||||
>
|
||||
{{ auth()->user()->initials() }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div class="grid flex-1 text-start text-sm leading-tight">
|
||||
<span class="truncate font-semibold">{{ auth()->user()->name }}</span>
|
||||
<span class="truncate text-xs">{{ auth()->user()->email }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</flux:menu.radio.group>
|
||||
|
||||
<flux:menu.separator />
|
||||
|
||||
<flux:menu.radio.group>
|
||||
<flux:menu.item :href="route('settings.profile')" icon="cog" wire:navigate>{{ __('Settings') }}</flux:menu.item>
|
||||
</flux:menu.radio.group>
|
||||
|
||||
<flux:menu.separator />
|
||||
|
||||
<form method="POST" action="{{ route('logout') }}" class="w-full">
|
||||
@csrf
|
||||
<flux:menu.item as="button" type="submit" icon="arrow-right-start-on-rectangle" class="w-full">
|
||||
{{ __('Log Out') }}
|
||||
</flux:menu.item>
|
||||
</form>
|
||||
</flux:menu>
|
||||
</flux:dropdown>
|
||||
</flux:header>
|
||||
|
||||
<!-- Mobile Menu -->
|
||||
<flux:sidebar stashable sticky class="lg:hidden border-e border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<flux:sidebar.toggle class="lg:hidden" icon="x-mark" />
|
||||
|
||||
<a href="{{ route('dashboard') }}" class="ms-1 flex items-center space-x-2 rtl:space-x-reverse" wire:navigate>
|
||||
<x-app-logo />
|
||||
</a>
|
||||
|
||||
<flux:navlist variant="outline">
|
||||
<flux:navlist.group :heading="__('Platform')">
|
||||
<flux:navlist.item icon="layout-grid" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>
|
||||
{{ __('Dashboard') }}
|
||||
</flux:navlist.item>
|
||||
</flux:navlist.group>
|
||||
</flux:navlist>
|
||||
|
||||
<flux:spacer />
|
||||
|
||||
<flux:navlist variant="outline">
|
||||
<flux:navlist.item icon="folder-git-2" href="https://github.com/laravel/livewire-starter-kit" target="_blank">
|
||||
{{ __('Repository') }}
|
||||
</flux:navlist.item>
|
||||
|
||||
<flux:navlist.item icon="book-open-text" href="https://laravel.com/docs/starter-kits#livewire" target="_blank">
|
||||
{{ __('Documentation') }}
|
||||
</flux:navlist.item>
|
||||
</flux:navlist>
|
||||
</flux:sidebar>
|
||||
|
||||
{{ $slot }}
|
||||
|
||||
@fluxScripts
|
||||
</body>
|
||||
</html>
|
132
resources/views/components/layouts/app/sidebar.blade.php
Normal file
132
resources/views/components/layouts/app/sidebar.blade.php
Normal file
@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||
<head>
|
||||
@include('partials.head')
|
||||
</head>
|
||||
<body class="min-h-screen bg-white dark:bg-zinc-800">
|
||||
<flux:sidebar sticky stashable class="border-e border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<flux:sidebar.toggle class="lg:hidden" icon="x-mark" />
|
||||
|
||||
<a href="{{ route('dashboard') }}" class="me-5 flex items-center space-x-2 rtl:space-x-reverse" wire:navigate>
|
||||
<x-app-logo />
|
||||
</a>
|
||||
|
||||
<flux:navlist variant="outline">
|
||||
<flux:navlist.group :heading="__('Platform')" class="grid">
|
||||
<flux:navlist.item icon="home" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>{{ __('Dashboard') }}</flux:navlist.item>
|
||||
</flux:navlist.group>
|
||||
</flux:navlist>
|
||||
|
||||
<flux:spacer />
|
||||
|
||||
<flux:navlist variant="outline">
|
||||
<flux:navlist.item icon="folder-git-2" href="https://github.com/laravel/livewire-starter-kit" target="_blank">
|
||||
{{ __('Repository') }}
|
||||
</flux:navlist.item>
|
||||
|
||||
<flux:navlist.item icon="book-open-text" href="https://laravel.com/docs/starter-kits#livewire" target="_blank">
|
||||
{{ __('Documentation') }}
|
||||
</flux:navlist.item>
|
||||
</flux:navlist>
|
||||
|
||||
<!-- Desktop User Menu -->
|
||||
<flux:dropdown position="bottom" align="start">
|
||||
<flux:profile
|
||||
:name="auth()->user()->name"
|
||||
:initials="auth()->user()->initials()"
|
||||
icon-trailing="chevrons-up-down"
|
||||
/>
|
||||
|
||||
<flux:menu class="w-[220px]">
|
||||
<flux:menu.radio.group>
|
||||
<div class="p-0 text-sm font-normal">
|
||||
<div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm">
|
||||
<span class="relative flex h-8 w-8 shrink-0 overflow-hidden rounded-lg">
|
||||
<span
|
||||
class="flex h-full w-full items-center justify-center rounded-lg bg-neutral-200 text-black dark:bg-neutral-700 dark:text-white"
|
||||
>
|
||||
{{ auth()->user()->initials() }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div class="grid flex-1 text-start text-sm leading-tight">
|
||||
<span class="truncate font-semibold">{{ auth()->user()->name }}</span>
|
||||
<span class="truncate text-xs">{{ auth()->user()->email }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</flux:menu.radio.group>
|
||||
|
||||
<flux:menu.separator />
|
||||
|
||||
<flux:menu.radio.group>
|
||||
<flux:menu.item :href="route('settings.profile')" icon="cog" wire:navigate>{{ __('Settings') }}</flux:menu.item>
|
||||
</flux:menu.radio.group>
|
||||
|
||||
<flux:menu.separator />
|
||||
|
||||
<form method="POST" action="{{ route('logout') }}" class="w-full">
|
||||
@csrf
|
||||
<flux:menu.item as="button" type="submit" icon="arrow-right-start-on-rectangle" class="w-full">
|
||||
{{ __('Log Out') }}
|
||||
</flux:menu.item>
|
||||
</form>
|
||||
</flux:menu>
|
||||
</flux:dropdown>
|
||||
</flux:sidebar>
|
||||
|
||||
<!-- Mobile User Menu -->
|
||||
<flux:header class="lg:hidden">
|
||||
<flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left" />
|
||||
|
||||
<flux:spacer />
|
||||
|
||||
<flux:dropdown position="top" align="end">
|
||||
<flux:profile
|
||||
:initials="auth()->user()->initials()"
|
||||
icon-trailing="chevron-down"
|
||||
/>
|
||||
|
||||
<flux:menu>
|
||||
<flux:menu.radio.group>
|
||||
<div class="p-0 text-sm font-normal">
|
||||
<div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm">
|
||||
<span class="relative flex h-8 w-8 shrink-0 overflow-hidden rounded-lg">
|
||||
<span
|
||||
class="flex h-full w-full items-center justify-center rounded-lg bg-neutral-200 text-black dark:bg-neutral-700 dark:text-white"
|
||||
>
|
||||
{{ auth()->user()->initials() }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div class="grid flex-1 text-start text-sm leading-tight">
|
||||
<span class="truncate font-semibold">{{ auth()->user()->name }}</span>
|
||||
<span class="truncate text-xs">{{ auth()->user()->email }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</flux:menu.radio.group>
|
||||
|
||||
<flux:menu.separator />
|
||||
|
||||
<flux:menu.radio.group>
|
||||
<flux:menu.item :href="route('settings.profile')" icon="cog" wire:navigate>{{ __('Settings') }}</flux:menu.item>
|
||||
</flux:menu.radio.group>
|
||||
|
||||
<flux:menu.separator />
|
||||
|
||||
<form method="POST" action="{{ route('logout') }}" class="w-full">
|
||||
@csrf
|
||||
<flux:menu.item as="button" type="submit" icon="arrow-right-start-on-rectangle" class="w-full">
|
||||
{{ __('Log Out') }}
|
||||
</flux:menu.item>
|
||||
</form>
|
||||
</flux:menu>
|
||||
</flux:dropdown>
|
||||
</flux:header>
|
||||
|
||||
{{ $slot }}
|
||||
|
||||
@fluxScripts
|
||||
</body>
|
||||
</html>
|
3
resources/views/components/layouts/auth.blade.php
Normal file
3
resources/views/components/layouts/auth.blade.php
Normal file
@ -0,0 +1,3 @@
|
||||
<x-layouts.auth.simple :title="$title ?? null">
|
||||
{{ $slot }}
|
||||
</x-layouts.auth.simple>
|
26
resources/views/components/layouts/auth/card.blade.php
Normal file
26
resources/views/components/layouts/auth/card.blade.php
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||
<head>
|
||||
@include('partials.head')
|
||||
</head>
|
||||
<body class="min-h-screen bg-neutral-100 antialiased dark:bg-linear-to-b dark:from-neutral-950 dark:to-neutral-900">
|
||||
<div class="bg-muted flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
|
||||
<div class="flex w-full max-w-md flex-col gap-6">
|
||||
<a href="{{ route('home') }}" class="flex flex-col items-center gap-2 font-medium" wire:navigate>
|
||||
<span class="flex h-9 w-9 items-center justify-center rounded-md">
|
||||
<x-app-logo-icon class="size-9 fill-current text-black dark:text-white" />
|
||||
</span>
|
||||
|
||||
<span class="sr-only">{{ config('app.name', 'Laravel') }}</span>
|
||||
</a>
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="rounded-xl border bg-white dark:bg-stone-950 dark:border-stone-800 text-stone-800 shadow-xs">
|
||||
<div class="px-10 py-8">{{ $slot }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@fluxScripts
|
||||
</body>
|
||||
</html>
|
22
resources/views/components/layouts/auth/simple.blade.php
Normal file
22
resources/views/components/layouts/auth/simple.blade.php
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||
<head>
|
||||
@include('partials.head')
|
||||
</head>
|
||||
<body class="min-h-screen bg-white antialiased dark:bg-linear-to-b dark:from-neutral-950 dark:to-neutral-900">
|
||||
<div class="bg-background flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
|
||||
<div class="flex w-full max-w-sm flex-col gap-2">
|
||||
<a href="{{ route('home') }}" class="flex flex-col items-center gap-2 font-medium" wire:navigate>
|
||||
<span class="flex h-9 w-9 mb-1 items-center justify-center rounded-md">
|
||||
<x-app-logo-icon class="size-9 fill-current text-black dark:text-white" />
|
||||
</span>
|
||||
<span class="sr-only">{{ config('app.name', 'Laravel') }}</span>
|
||||
</a>
|
||||
<div class="flex flex-col gap-6">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@fluxScripts
|
||||
</body>
|
||||
</html>
|
43
resources/views/components/layouts/auth/split.blade.php
Normal file
43
resources/views/components/layouts/auth/split.blade.php
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||
<head>
|
||||
@include('partials.head')
|
||||
</head>
|
||||
<body class="min-h-screen bg-white antialiased dark:bg-linear-to-b dark:from-neutral-950 dark:to-neutral-900">
|
||||
<div class="relative grid h-dvh flex-col items-center justify-center px-8 sm:px-0 lg:max-w-none lg:grid-cols-2 lg:px-0">
|
||||
<div class="bg-muted relative hidden h-full flex-col p-10 text-white lg:flex dark:border-e dark:border-neutral-800">
|
||||
<div class="absolute inset-0 bg-neutral-900"></div>
|
||||
<a href="{{ route('home') }}" class="relative z-20 flex items-center text-lg font-medium" wire:navigate>
|
||||
<span class="flex h-10 w-10 items-center justify-center rounded-md">
|
||||
<x-app-logo-icon class="me-2 h-7 fill-current text-white" />
|
||||
</span>
|
||||
{{ config('app.name', 'Laravel') }}
|
||||
</a>
|
||||
|
||||
@php
|
||||
[$message, $author] = str(Illuminate\Foundation\Inspiring::quotes()->random())->explode('-');
|
||||
@endphp
|
||||
|
||||
<div class="relative z-20 mt-auto">
|
||||
<blockquote class="space-y-2">
|
||||
<flux:heading size="lg">“{{ trim($message) }}”</flux:heading>
|
||||
<footer><flux:heading>{{ trim($author) }}</flux:heading></footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full lg:p-8">
|
||||
<div class="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]">
|
||||
<a href="{{ route('home') }}" class="z-20 flex flex-col items-center gap-2 font-medium lg:hidden" wire:navigate>
|
||||
<span class="flex h-9 w-9 items-center justify-center rounded-md">
|
||||
<x-app-logo-icon class="size-9 fill-current text-black dark:text-white" />
|
||||
</span>
|
||||
|
||||
<span class="sr-only">{{ config('app.name', 'Laravel') }}</span>
|
||||
</a>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@fluxScripts
|
||||
</body>
|
||||
</html>
|
19
resources/views/components/layouts/guest.blade.php
Normal file
19
resources/views/components/layouts/guest.blade.php
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||
|
||||
<head>
|
||||
@include('partials.head')
|
||||
</head>
|
||||
|
||||
<body class="min-h-screen bg-white antialiased dark:bg-linear-to-b dark:from-neutral-950 dark:to-neutral-900">
|
||||
<div class="bg-background flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
|
||||
<div class="flex w-full flex-col gap-2">
|
||||
<div class="flex flex-col gap-6">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@fluxScripts
|
||||
</body>
|
||||
|
||||
</html>
|
12
resources/views/components/placeholder-pattern.blade.php
Normal file
12
resources/views/components/placeholder-pattern.blade.php
Normal file
@ -0,0 +1,12 @@
|
||||
@props([
|
||||
'id' => uniqid(),
|
||||
])
|
||||
|
||||
<svg {{ $attributes }} fill="none">
|
||||
<defs>
|
||||
<pattern id="pattern-{{ $id }}" x="0" y="0" width="8" height="8" patternUnits="userSpaceOnUse">
|
||||
<path d="M-1 5L5 -1M3 9L8.5 3.5" stroke-width="0.5"></path>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect stroke="none" fill="url(#pattern-{{ $id }})" width="100%" height="100%"></rect>
|
||||
</svg>
|
20
resources/views/components/settings/layout.blade.php
Normal file
20
resources/views/components/settings/layout.blade.php
Normal file
@ -0,0 +1,20 @@
|
||||
<div class="flex items-start max-md:flex-col">
|
||||
<div class="me-10 w-full pb-4 md:w-[220px]">
|
||||
<flux:navlist>
|
||||
<flux:navlist.item :href="route('settings.profile')" wire:navigate>{{ __('Profile') }}</flux:navlist.item>
|
||||
<flux:navlist.item :href="route('settings.password')" wire:navigate>{{ __('Password') }}</flux:navlist.item>
|
||||
<flux:navlist.item :href="route('settings.appearance')" wire:navigate>{{ __('Appearance') }}</flux:navlist.item>
|
||||
</flux:navlist>
|
||||
</div>
|
||||
|
||||
<flux:separator class="md:hidden" />
|
||||
|
||||
<div class="flex-1 self-stretch max-md:pt-6">
|
||||
<flux:heading>{{ $heading ?? '' }}</flux:heading>
|
||||
<flux:subheading>{{ $subheading ?? '' }}</flux:subheading>
|
||||
|
||||
<div class="mt-5 w-full max-w-lg">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
24
resources/views/dashboard.blade.php
Normal file
24
resources/views/dashboard.blade.php
Normal file
@ -0,0 +1,24 @@
|
||||
<x-layouts.app :title="__('Applications')">
|
||||
<div class="flex h-full w-full flex-1 flex-col gap-4 rounded-xl">
|
||||
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||
<div
|
||||
class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-placeholder-pattern
|
||||
class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
|
||||
</div>
|
||||
<div
|
||||
class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-placeholder-pattern
|
||||
class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
|
||||
</div>
|
||||
<div
|
||||
class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-placeholder-pattern
|
||||
class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative h-full flex-1 overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-placeholder-pattern class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts.app>
|
47
resources/views/flux/icon/book-open-text.blade.php
Normal file
47
resources/views/flux/icon/book-open-text.blade.php
Normal file
@ -0,0 +1,47 @@
|
||||
{{-- Credit: Lucide (https://lucide.dev) --}}
|
||||
|
||||
@props([
|
||||
'variant' => 'outline',
|
||||
])
|
||||
|
||||
@php
|
||||
if ($variant === 'solid') {
|
||||
throw new \Exception('The "solid" variant is not supported in Lucide.');
|
||||
}
|
||||
|
||||
$classes = Flux::classes('shrink-0')->add(
|
||||
match ($variant) {
|
||||
'outline' => '[:where(&)]:size-6',
|
||||
'solid' => '[:where(&)]:size-6',
|
||||
'mini' => '[:where(&)]:size-5',
|
||||
'micro' => '[:where(&)]:size-4',
|
||||
},
|
||||
);
|
||||
|
||||
$strokeWidth = match ($variant) {
|
||||
'outline' => 2,
|
||||
'mini' => 2.25,
|
||||
'micro' => 2.5,
|
||||
};
|
||||
@endphp
|
||||
|
||||
<svg
|
||||
{{ $attributes->class($classes) }}
|
||||
data-flux-icon
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="{{ $strokeWidth }}"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
data-slot="icon"
|
||||
>
|
||||
<path d="M12 7v14" />
|
||||
<path d="M16 12h2" />
|
||||
<path d="M16 8h2" />
|
||||
<path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z" />
|
||||
<path d="M6 12h2" />
|
||||
<path d="M6 8h2" />
|
||||
</svg>
|
43
resources/views/flux/icon/chevrons-up-down.blade.php
Normal file
43
resources/views/flux/icon/chevrons-up-down.blade.php
Normal file
@ -0,0 +1,43 @@
|
||||
{{-- Credit: Lucide (https://lucide.dev) --}}
|
||||
|
||||
@props([
|
||||
'variant' => 'outline',
|
||||
])
|
||||
|
||||
@php
|
||||
if ($variant === 'solid') {
|
||||
throw new \Exception('The "solid" variant is not supported in Lucide.');
|
||||
}
|
||||
|
||||
$classes = Flux::classes('shrink-0')->add(
|
||||
match ($variant) {
|
||||
'outline' => '[:where(&)]:size-6',
|
||||
'solid' => '[:where(&)]:size-6',
|
||||
'mini' => '[:where(&)]:size-5',
|
||||
'micro' => '[:where(&)]:size-4',
|
||||
},
|
||||
);
|
||||
|
||||
$strokeWidth = match ($variant) {
|
||||
'outline' => 2,
|
||||
'mini' => 2.25,
|
||||
'micro' => 2.5,
|
||||
};
|
||||
@endphp
|
||||
|
||||
<svg
|
||||
{{ $attributes->class($classes) }}
|
||||
data-flux-icon
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="{{ $strokeWidth }}"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
data-slot="icon"
|
||||
>
|
||||
<path d="m7 15 5 5 5-5" />
|
||||
<path d="m7 9 5-5 5 5" />
|
||||
</svg>
|
45
resources/views/flux/icon/folder-git-2.blade.php
Normal file
45
resources/views/flux/icon/folder-git-2.blade.php
Normal file
@ -0,0 +1,45 @@
|
||||
{{-- Credit: Lucide (https://lucide.dev) --}}
|
||||
|
||||
@props([
|
||||
'variant' => 'outline',
|
||||
])
|
||||
|
||||
@php
|
||||
if ($variant === 'solid') {
|
||||
throw new \Exception('The "solid" variant is not supported in Lucide.');
|
||||
}
|
||||
|
||||
$classes = Flux::classes('shrink-0')->add(
|
||||
match ($variant) {
|
||||
'outline' => '[:where(&)]:size-6',
|
||||
'solid' => '[:where(&)]:size-6',
|
||||
'mini' => '[:where(&)]:size-5',
|
||||
'micro' => '[:where(&)]:size-4',
|
||||
},
|
||||
);
|
||||
|
||||
$strokeWidth = match ($variant) {
|
||||
'outline' => 2,
|
||||
'mini' => 2.25,
|
||||
'micro' => 2.5,
|
||||
};
|
||||
@endphp
|
||||
|
||||
<svg
|
||||
{{ $attributes->class($classes) }}
|
||||
data-flux-icon
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="{{ $strokeWidth }}"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
data-slot="icon"
|
||||
>
|
||||
<path d="M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v5" />
|
||||
<circle cx="13" cy="12" r="2" />
|
||||
<path d="M18 19c-2.8 0-5-2.2-5-5v8" />
|
||||
<circle cx="20" cy="19" r="2" />
|
||||
</svg>
|
45
resources/views/flux/icon/layout-grid.blade.php
Normal file
45
resources/views/flux/icon/layout-grid.blade.php
Normal file
@ -0,0 +1,45 @@
|
||||
{{-- Credit: Lucide (https://lucide.dev) --}}
|
||||
|
||||
@props([
|
||||
'variant' => 'outline',
|
||||
])
|
||||
|
||||
@php
|
||||
if ($variant === 'solid') {
|
||||
throw new \Exception('The "solid" variant is not supported in Lucide.');
|
||||
}
|
||||
|
||||
$classes = Flux::classes('shrink-0')->add(
|
||||
match ($variant) {
|
||||
'outline' => '[:where(&)]:size-6',
|
||||
'solid' => '[:where(&)]:size-6',
|
||||
'mini' => '[:where(&)]:size-5',
|
||||
'micro' => '[:where(&)]:size-4',
|
||||
},
|
||||
);
|
||||
|
||||
$strokeWidth = match ($variant) {
|
||||
'outline' => 2,
|
||||
'mini' => 2.25,
|
||||
'micro' => 2.5,
|
||||
};
|
||||
@endphp
|
||||
|
||||
<svg
|
||||
{{ $attributes->class($classes) }}
|
||||
data-flux-icon
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="{{ $strokeWidth }}"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
data-slot="icon"
|
||||
>
|
||||
<rect width="7" height="7" x="3" y="3" rx="1" />
|
||||
<rect width="7" height="7" x="14" y="3" rx="1" />
|
||||
<rect width="7" height="7" x="14" y="14" rx="1" />
|
||||
<rect width="7" height="7" x="3" y="14" rx="1" />
|
||||
</svg>
|
51
resources/views/flux/navlist/group.blade.php
Normal file
51
resources/views/flux/navlist/group.blade.php
Normal file
@ -0,0 +1,51 @@
|
||||
@props([
|
||||
'expandable' => false,
|
||||
'expanded' => true,
|
||||
'heading' => null,
|
||||
])
|
||||
|
||||
<?php if ($expandable && $heading): ?>
|
||||
|
||||
<ui-disclosure
|
||||
{{ $attributes->class('group/disclosure') }}
|
||||
@if ($expanded === true) open @endif
|
||||
data-flux-navlist-group
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="group/disclosure-button mb-[2px] flex h-10 w-full items-center rounded-lg text-zinc-500 hover:bg-zinc-800/5 hover:text-zinc-800 lg:h-8 dark:text-white/80 dark:hover:bg-white/[7%] dark:hover:text-white"
|
||||
>
|
||||
<div class="ps-3 pe-4">
|
||||
<flux:icon.chevron-down class="hidden size-3! group-data-open/disclosure-button:block" />
|
||||
<flux:icon.chevron-right class="block size-3! group-data-open/disclosure-button:hidden" />
|
||||
</div>
|
||||
|
||||
<span class="text-sm font-medium leading-none">{{ $heading }}</span>
|
||||
</button>
|
||||
|
||||
<div class="relative hidden space-y-[2px] ps-7 data-open:block" @if ($expanded === true) data-open @endif>
|
||||
<div class="absolute inset-y-[3px] start-0 ms-4 w-px bg-zinc-200 dark:bg-white/30"></div>
|
||||
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</ui-disclosure>
|
||||
|
||||
<?php elseif ($heading): ?>
|
||||
|
||||
<div {{ $attributes->class('block space-y-[2px]') }}>
|
||||
<div class="px-1 py-2">
|
||||
<div class="text-xs leading-none text-zinc-400">{{ $heading }}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<div {{ $attributes->class('block space-y-[2px]') }}>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
56
resources/views/livewire/application-form.blade.php
Normal file
56
resources/views/livewire/application-form.blade.php
Normal file
@ -0,0 +1,56 @@
|
||||
<div class="max-w-2xl mx-auto mt-10 flex flex-col gap-6">
|
||||
@if (session()->has('message'))
|
||||
@if ($applicationUuid)
|
||||
<div class="p-5 mb-4 dark:bg-green-600/50 rounded-lg">
|
||||
<flux:heading>Your application has been submitted</flux:heading>
|
||||
<flux:text class="mt-2">
|
||||
You can check its status here: <flux:link
|
||||
href="{{ route('application.status', ['uuid' => $applicationUuid]) }}">View Application Status
|
||||
</flux:link>
|
||||
</flux:text>
|
||||
<flux:text class="mt-2">
|
||||
Please save or bookmark that link, as the approval process can take roughly 24-48 hours.
|
||||
</flux:text>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if (!$applicationUuid)
|
||||
<form wire:submit.prevent="submit" enctype="multipart/form-data">
|
||||
<div class="mb-6">
|
||||
<div class="p-5 mb-4 dark:bg-pink-950/50 rounded-lg">
|
||||
<flux:heading>Here you can submit your application</flux:heading>
|
||||
<flux:text class="mt-2">
|
||||
To apply, simply fill out the form below and upload at least one loli photo.
|
||||
After submitting, you'll receive a unique link — make sure to save it! You can use that
|
||||
link to check the status of your application, and if everything is approved, you'll also
|
||||
receive
|
||||
your registration token there.
|
||||
</flux:text>
|
||||
</div>
|
||||
<flux:textarea wire:model="message" label="Why do you want to join?" placeholder="Cunny 😭" />
|
||||
<br>
|
||||
<flux:input type="file" wire:model="photos" label="Loli Photos (max. 8MB)" multiple />
|
||||
<div class="mt-4">
|
||||
<div class="flex">
|
||||
<flux:input label="Captcha" wire:model.defer="captchaInput" />
|
||||
<img src="{{ $captcha }}" alt="captcha" wire:click="refreshCaptcha"
|
||||
class="cursor-pointer ml-3 mt-7 h-10 rounded-lg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<flux:button wire:click="submit">Submit Application</flux:button>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
@if ($photos)
|
||||
<div class="mt-4">
|
||||
<h3 class="font-bold">Photo Preview:</h3>
|
||||
<div class="flex gap-4 mt-2">
|
||||
@foreach ($photos as $photo)
|
||||
<img src="{{ $photo->temporaryUrl() }}" class="w-24 h-24 object-cover rounded">
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
24
resources/views/livewire/auth/confirm-password.blade.php
Normal file
24
resources/views/livewire/auth/confirm-password.blade.php
Normal file
@ -0,0 +1,24 @@
|
||||
<div class="flex flex-col gap-6">
|
||||
<x-auth-header
|
||||
:title="__('Confirm password')"
|
||||
:description="__('This is a secure area of the application. Please confirm your password before continuing.')"
|
||||
/>
|
||||
|
||||
<!-- Session Status -->
|
||||
<x-auth-session-status class="text-center" :status="session('status')" />
|
||||
|
||||
<form wire:submit="confirmPassword" class="flex flex-col gap-6">
|
||||
<!-- Password -->
|
||||
<flux:input
|
||||
wire:model="password"
|
||||
:label="__('Password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
:placeholder="__('Password')"
|
||||
viewable
|
||||
/>
|
||||
|
||||
<flux:button variant="primary" type="submit" class="w-full">{{ __('Confirm') }}</flux:button>
|
||||
</form>
|
||||
</div>
|
26
resources/views/livewire/auth/forgot-password.blade.php
Normal file
26
resources/views/livewire/auth/forgot-password.blade.php
Normal file
@ -0,0 +1,26 @@
|
||||
<div class="flex flex-col gap-6">
|
||||
<x-auth-header :title="__('Forgot password')" :description="__('Enter your email to receive a password reset link')" />
|
||||
|
||||
<!-- Session Status -->
|
||||
<x-auth-session-status class="text-center" :status="session('status')" />
|
||||
|
||||
<form wire:submit="sendPasswordResetLink" class="flex flex-col gap-6">
|
||||
<!-- Email Address -->
|
||||
<flux:input
|
||||
wire:model="email"
|
||||
:label="__('Email Address')"
|
||||
type="email"
|
||||
required
|
||||
autofocus
|
||||
placeholder="email@example.com"
|
||||
viewable
|
||||
/>
|
||||
|
||||
<flux:button variant="primary" type="submit" class="w-full">{{ __('Email password reset link') }}</flux:button>
|
||||
</form>
|
||||
|
||||
<div class="space-x-1 rtl:space-x-reverse text-center text-sm text-zinc-400">
|
||||
{{ __('Or, return to') }}
|
||||
<flux:link :href="route('login')" wire:navigate>{{ __('log in') }}</flux:link>
|
||||
</div>
|
||||
</div>
|
52
resources/views/livewire/auth/login.blade.php
Normal file
52
resources/views/livewire/auth/login.blade.php
Normal file
@ -0,0 +1,52 @@
|
||||
<div class="flex flex-col gap-6">
|
||||
<x-auth-header :title="__('Log in to your account')" :description="__('Enter your email and password below to log in')" />
|
||||
|
||||
<!-- Session Status -->
|
||||
<x-auth-session-status class="text-center" :status="session('status')" />
|
||||
|
||||
<form wire:submit="login" class="flex flex-col gap-6">
|
||||
<!-- Email Address -->
|
||||
<flux:input
|
||||
wire:model="email"
|
||||
:label="__('Email address')"
|
||||
type="email"
|
||||
required
|
||||
autofocus
|
||||
autocomplete="email"
|
||||
placeholder="email@example.com"
|
||||
/>
|
||||
|
||||
<!-- Password -->
|
||||
<div class="relative">
|
||||
<flux:input
|
||||
wire:model="password"
|
||||
:label="__('Password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="current-password"
|
||||
:placeholder="__('Password')"
|
||||
viewable
|
||||
/>
|
||||
|
||||
@if (Route::has('password.request'))
|
||||
<flux:link class="absolute end-0 top-0 text-sm" :href="route('password.request')" wire:navigate>
|
||||
{{ __('Forgot your password?') }}
|
||||
</flux:link>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Remember Me -->
|
||||
<flux:checkbox wire:model="remember" :label="__('Remember me')" />
|
||||
|
||||
<div class="flex items-center justify-end">
|
||||
<flux:button variant="primary" type="submit" class="w-full">{{ __('Log in') }}</flux:button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if (Route::has('register'))
|
||||
<div class="space-x-1 rtl:space-x-reverse text-center text-sm text-zinc-600 dark:text-zinc-400">
|
||||
{{ __('Don\'t have an account?') }}
|
||||
<flux:link :href="route('register')" wire:navigate>{{ __('Sign up') }}</flux:link>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
62
resources/views/livewire/auth/register.blade.php
Normal file
62
resources/views/livewire/auth/register.blade.php
Normal file
@ -0,0 +1,62 @@
|
||||
<div class="flex flex-col gap-6">
|
||||
<x-auth-header :title="__('Create an account')" :description="__('Enter your details below to create your account')" />
|
||||
|
||||
<!-- Session Status -->
|
||||
<x-auth-session-status class="text-center" :status="session('status')" />
|
||||
|
||||
<form wire:submit="register" class="flex flex-col gap-6">
|
||||
<!-- Name -->
|
||||
<flux:input
|
||||
wire:model="name"
|
||||
:label="__('Name')"
|
||||
type="text"
|
||||
required
|
||||
autofocus
|
||||
autocomplete="name"
|
||||
:placeholder="__('Full name')"
|
||||
/>
|
||||
|
||||
<!-- Email Address -->
|
||||
<flux:input
|
||||
wire:model="email"
|
||||
:label="__('Email address')"
|
||||
type="email"
|
||||
required
|
||||
autocomplete="email"
|
||||
placeholder="email@example.com"
|
||||
/>
|
||||
|
||||
<!-- Password -->
|
||||
<flux:input
|
||||
wire:model="password"
|
||||
:label="__('Password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
:placeholder="__('Password')"
|
||||
viewable
|
||||
/>
|
||||
|
||||
<!-- Confirm Password -->
|
||||
<flux:input
|
||||
wire:model="password_confirmation"
|
||||
:label="__('Confirm password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
:placeholder="__('Confirm password')"
|
||||
viewable
|
||||
/>
|
||||
|
||||
<div class="flex items-center justify-end">
|
||||
<flux:button type="submit" variant="primary" class="w-full">
|
||||
{{ __('Create account') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="space-x-1 rtl:space-x-reverse text-center text-sm text-zinc-600 dark:text-zinc-400">
|
||||
{{ __('Already have an account?') }}
|
||||
<flux:link :href="route('login')" wire:navigate>{{ __('Log in') }}</flux:link>
|
||||
</div>
|
||||
</div>
|
45
resources/views/livewire/auth/reset-password.blade.php
Normal file
45
resources/views/livewire/auth/reset-password.blade.php
Normal file
@ -0,0 +1,45 @@
|
||||
<div class="flex flex-col gap-6">
|
||||
<x-auth-header :title="__('Reset password')" :description="__('Please enter your new password below')" />
|
||||
|
||||
<!-- Session Status -->
|
||||
<x-auth-session-status class="text-center" :status="session('status')" />
|
||||
|
||||
<form wire:submit="resetPassword" class="flex flex-col gap-6">
|
||||
<!-- Email Address -->
|
||||
<flux:input
|
||||
wire:model="email"
|
||||
:label="__('Email')"
|
||||
type="email"
|
||||
required
|
||||
autocomplete="email"
|
||||
/>
|
||||
|
||||
<!-- Password -->
|
||||
<flux:input
|
||||
wire:model="password"
|
||||
:label="__('Password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
:placeholder="__('Password')"
|
||||
viewable
|
||||
/>
|
||||
|
||||
<!-- Confirm Password -->
|
||||
<flux:input
|
||||
wire:model="password_confirmation"
|
||||
:label="__('Confirm password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
:placeholder="__('Confirm password')"
|
||||
viewable
|
||||
/>
|
||||
|
||||
<div class="flex items-center justify-end">
|
||||
<flux:button type="submit" variant="primary" class="w-full">
|
||||
{{ __('Reset password') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
21
resources/views/livewire/auth/verify-email.blade.php
Normal file
21
resources/views/livewire/auth/verify-email.blade.php
Normal file
@ -0,0 +1,21 @@
|
||||
<div class="mt-4 flex flex-col gap-6">
|
||||
<flux:text class="text-center">
|
||||
{{ __('Please verify your email address by clicking on the link we just emailed to you.') }}
|
||||
</flux:text>
|
||||
|
||||
@if (session('status') == 'verification-link-sent')
|
||||
<flux:text class="text-center font-medium !dark:text-green-400 !text-green-600">
|
||||
{{ __('A new verification link has been sent to the email address you provided during registration.') }}
|
||||
</flux:text>
|
||||
@endif
|
||||
|
||||
<div class="flex flex-col items-center justify-between space-y-3">
|
||||
<flux:button wire:click="sendVerification" variant="primary" class="w-full">
|
||||
{{ __('Resend verification email') }}
|
||||
</flux:button>
|
||||
|
||||
<flux:link class="text-sm cursor-pointer" wire:click="logout">
|
||||
{{ __('Log out') }}
|
||||
</flux:link>
|
||||
</div>
|
||||
</div>
|
11
resources/views/livewire/settings/appearance.blade.php
Normal file
11
resources/views/livewire/settings/appearance.blade.php
Normal file
@ -0,0 +1,11 @@
|
||||
<section class="w-full">
|
||||
@include('partials.settings-heading')
|
||||
|
||||
<x-settings.layout :heading="__('Appearance')" :subheading=" __('Update the appearance settings for your account')">
|
||||
<flux:radio.group x-data variant="segmented" x-model="$flux.appearance">
|
||||
<flux:radio value="light" icon="sun">{{ __('Light') }}</flux:radio>
|
||||
<flux:radio value="dark" icon="moon">{{ __('Dark') }}</flux:radio>
|
||||
<flux:radio value="system" icon="computer-desktop">{{ __('System') }}</flux:radio>
|
||||
</flux:radio.group>
|
||||
</x-settings.layout>
|
||||
</section>
|
34
resources/views/livewire/settings/delete-user-form.blade.php
Normal file
34
resources/views/livewire/settings/delete-user-form.blade.php
Normal file
@ -0,0 +1,34 @@
|
||||
<section class="mt-10 space-y-6">
|
||||
<div class="relative mb-5">
|
||||
<flux:heading>{{ __('Delete account') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Delete your account and all of its resources') }}</flux:subheading>
|
||||
</div>
|
||||
|
||||
<flux:modal.trigger name="confirm-user-deletion">
|
||||
<flux:button variant="danger" x-data="" x-on:click.prevent="$dispatch('open-modal', 'confirm-user-deletion')">
|
||||
{{ __('Delete account') }}
|
||||
</flux:button>
|
||||
</flux:modal.trigger>
|
||||
|
||||
<flux:modal name="confirm-user-deletion" :show="$errors->isNotEmpty()" focusable class="max-w-lg">
|
||||
<form wire:submit="deleteUser" class="space-y-6">
|
||||
<div>
|
||||
<flux:heading size="lg">{{ __('Are you sure you want to delete your account?') }}</flux:heading>
|
||||
|
||||
<flux:subheading>
|
||||
{{ __('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.') }}
|
||||
</flux:subheading>
|
||||
</div>
|
||||
|
||||
<flux:input wire:model="password" :label="__('Password')" type="password" />
|
||||
|
||||
<div class="flex justify-end space-x-2 rtl:space-x-reverse">
|
||||
<flux:modal.close>
|
||||
<flux:button variant="filled">{{ __('Cancel') }}</flux:button>
|
||||
</flux:modal.close>
|
||||
|
||||
<flux:button variant="danger" type="submit">{{ __('Delete account') }}</flux:button>
|
||||
</div>
|
||||
</form>
|
||||
</flux:modal>
|
||||
</section>
|
39
resources/views/livewire/settings/password.blade.php
Normal file
39
resources/views/livewire/settings/password.blade.php
Normal file
@ -0,0 +1,39 @@
|
||||
<section class="w-full">
|
||||
@include('partials.settings-heading')
|
||||
|
||||
<x-settings.layout :heading="__('Update password')" :subheading="__('Ensure your account is using a long, random password to stay secure')">
|
||||
<form wire:submit="updatePassword" class="mt-6 space-y-6">
|
||||
<flux:input
|
||||
wire:model="current_password"
|
||||
:label="__('Current password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
<flux:input
|
||||
wire:model="password"
|
||||
:label="__('New password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<flux:input
|
||||
wire:model="password_confirmation"
|
||||
:label="__('Confirm Password')"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex items-center justify-end">
|
||||
<flux:button variant="primary" type="submit" class="w-full">{{ __('Save') }}</flux:button>
|
||||
</div>
|
||||
|
||||
<x-action-message class="me-3" on="password-updated">
|
||||
{{ __('Saved.') }}
|
||||
</x-action-message>
|
||||
</div>
|
||||
</form>
|
||||
</x-settings.layout>
|
||||
</section>
|
43
resources/views/livewire/settings/profile.blade.php
Normal file
43
resources/views/livewire/settings/profile.blade.php
Normal file
@ -0,0 +1,43 @@
|
||||
<section class="w-full">
|
||||
@include('partials.settings-heading')
|
||||
|
||||
<x-settings.layout :heading="__('Profile')" :subheading="__('Update your name and email address')">
|
||||
<form wire:submit="updateProfileInformation" class="my-6 w-full space-y-6">
|
||||
<flux:input wire:model="name" :label="__('Name')" type="text" required autofocus autocomplete="name" />
|
||||
|
||||
<div>
|
||||
<flux:input wire:model="email" :label="__('Email')" type="email" required autocomplete="email" />
|
||||
|
||||
@if (auth()->user() instanceof \Illuminate\Contracts\Auth\MustVerifyEmail &&! auth()->user()->hasVerifiedEmail())
|
||||
<div>
|
||||
<flux:text class="mt-4">
|
||||
{{ __('Your email address is unverified.') }}
|
||||
|
||||
<flux:link class="text-sm cursor-pointer" wire:click.prevent="resendVerificationNotification">
|
||||
{{ __('Click here to re-send the verification email.') }}
|
||||
</flux:link>
|
||||
</flux:text>
|
||||
|
||||
@if (session('status') === 'verification-link-sent')
|
||||
<flux:text class="mt-2 font-medium !dark:text-green-400 !text-green-600">
|
||||
{{ __('A new verification link has been sent to your email address.') }}
|
||||
</flux:text>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex items-center justify-end">
|
||||
<flux:button variant="primary" type="submit" class="w-full">{{ __('Save') }}</flux:button>
|
||||
</div>
|
||||
|
||||
<x-action-message class="me-3" on="profile-updated">
|
||||
{{ __('Saved.') }}
|
||||
</x-action-message>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<livewire:settings.delete-user-form />
|
||||
</x-settings.layout>
|
||||
</section>
|
14
resources/views/partials/head.blade.php
Normal file
14
resources/views/partials/head.blade.php
Normal file
@ -0,0 +1,14 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<title>{{ $title ?? config('app.name') }}</title>
|
||||
|
||||
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=instrument-sans:400,500,600" rel="stylesheet" />
|
||||
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
@fluxAppearance
|
5
resources/views/partials/settings-heading.blade.php
Normal file
5
resources/views/partials/settings-heading.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
<div class="relative mb-6 w-full">
|
||||
<flux:heading size="xl" level="1">{{ __('Settings') }}</flux:heading>
|
||||
<flux:subheading size="lg" class="mb-6">{{ __('Manage your profile and account settings') }}</flux:subheading>
|
||||
<flux:separator variant="subtle" />
|
||||
</div>
|
32
routes/auth.php
Normal file
32
routes/auth.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Auth\VerifyEmailController;
|
||||
use App\Livewire\Auth\ConfirmPassword;
|
||||
use App\Livewire\Auth\ForgotPassword;
|
||||
use App\Livewire\Auth\Login;
|
||||
use App\Livewire\Auth\Register;
|
||||
use App\Livewire\Auth\ResetPassword;
|
||||
use App\Livewire\Auth\VerifyEmail;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::middleware('guest')->group(function () {
|
||||
Route::get('login', Login::class)->name('login');
|
||||
Route::get('register', Register::class)->name('register');
|
||||
Route::get('forgot-password', ForgotPassword::class)->name('password.request');
|
||||
Route::get('reset-password/{token}', ResetPassword::class)->name('password.reset');
|
||||
});
|
||||
|
||||
Route::middleware('auth')->group(function () {
|
||||
Route::get('verify-email', VerifyEmail::class)
|
||||
->name('verification.notice');
|
||||
|
||||
Route::get('verify-email/{id}/{hash}', VerifyEmailController::class)
|
||||
->middleware(['signed', 'throttle:6,1'])
|
||||
->name('verification.verify');
|
||||
|
||||
Route::get('confirm-password', ConfirmPassword::class)
|
||||
->name('password.confirm');
|
||||
});
|
||||
|
||||
Route::post('logout', App\Livewire\Actions\Logout::class)
|
||||
->name('logout');
|
8
routes/console.php
Normal file
8
routes/console.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Inspiring;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
Artisan::command('inspire', function () {
|
||||
$this->comment(Inspiring::quote());
|
||||
})->purpose('Display an inspiring quote');
|
27
routes/web.php
Normal file
27
routes/web.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Settings\Appearance;
|
||||
use App\Livewire\Settings\Password;
|
||||
use App\Livewire\Settings\Profile;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('/', App\Livewire\ApplicationForm::class)->name('home');
|
||||
|
||||
Route::view('dashboard', 'dashboard')
|
||||
->middleware(['auth', 'verified'])
|
||||
->name('dashboard');
|
||||
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::redirect('settings', 'settings/profile');
|
||||
|
||||
Route::get('settings/profile', Profile::class)->name('settings.profile');
|
||||
Route::get('settings/password', Password::class)->name('settings.password');
|
||||
Route::get('settings/appearance', Appearance::class)->name('settings.appearance');
|
||||
});
|
||||
|
||||
Route::get('/application-status/{uuid}', function ($uuid) {
|
||||
$application = App\Models\Application::where('uuid', $uuid)->firstOrFail();
|
||||
return view('application-status', compact('application'));
|
||||
})->name('application.status');
|
||||
|
||||
require __DIR__ . '/auth.php';
|
4
storage/app/.gitignore
vendored
Normal file
4
storage/app/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
*
|
||||
!private/
|
||||
!public/
|
||||
!.gitignore
|
2
storage/app/private/.gitignore
vendored
Normal file
2
storage/app/private/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user