updating env example file

This commit is contained in:
Brian 2022-03-30 13:23:25 -06:00
parent f96e7eb0aa
commit 74055ea11b
Signed by: brian
GPG Key ID: DE1A5390A3B84CD8
20 changed files with 850 additions and 77 deletions

View File

@ -1,3 +1,3 @@
#!/usr/bin/env bash
composer require itsgoingd/clockwork enlightn/security-checker
composer require --dev itsgoingd/clockwork enlightn/security-checker

View File

@ -1,10 +1,16 @@
APP_NAME=Invoicer
APP_NAME="App Name"
APP_ENV=local
APP_KEY=base64:hSCTwZ507IdKQ5QJHJ+mQw0DSMgDdAspasjwHCdiB8Y=
APP_DEBUG=true
APP_URL=https://invoicer.test
APP_DOMAIN=localhost
APP_URL="https://${APP_DOMAIN}"
APP_UID_BYTES=8
APP_JS_INTEGRITY_HASH=""
GIT_HASH="00000000"
GIT_TAG="x.x.x"
GIT_BRANCH="master"
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
@ -12,7 +18,7 @@ LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=mariadb
DB_PORT=3306
DB_DATABASE=invoicer_v3
DB_DATABASE=database_name
DB_USERNAME=root
DB_PASSWORD=root
@ -36,7 +42,7 @@ MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
MAIL_FROM_NAME="no-reply@${APP_DOMAIN}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Requests\Users;
use Illuminate\Foundation\Http\FormRequest;
class StoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return [
//
];
}
/**
* Prepare the data for validation.
*
* @throws \JsonException
*
* @return void
*/
protected function prepareForValidation(): void
{
// Use this if you want to have some JSON be converted from a string to an object(?)
//$this->merge(json_decode($this->payload, true, 512, JSON_THROW_ON_ERROR));
}
}

View File

@ -3,6 +3,7 @@
namespace App\Models;
use App\Models\Traits\HasUidTrait;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Prunable;
use Illuminate\Database\Eloquent\Relations\MorphOne;
@ -11,6 +12,7 @@ use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Jetstream\HasTeams;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
@ -119,28 +121,32 @@ class User extends Authenticatable
|
*/
/**
* Return the surname then (first)name separated by a comma.
*
* @since 1.0.0
*
* @return string
*/
public function getFullNameAttribute(): string
{
return "{$this->surname}, {$this->name}";
}
/**
* Return both the (first)name and surname.
*
* @since 1.0.0
*
* @return string
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
public function getNameFullAttribute(): string
public function fullName(): Attribute
{
return "{$this->name} {$this->surname}";
return Attribute::make(
get: fn ($value, $attributes) => "{$attributes['name']} {$attributes['surname']}",
);
}
/**
* Return the surname then (first)name separated by a comma.
*
* @since 1.0.0
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
public function fullNameReversed(): Attribute
{
return Attribute::make(
get: fn ($value, $attributes) => "{$attributes['surname']}, {$attributes['name']}",
);
}
/*

303
src/app/Support/Address.php Normal file
View File

@ -0,0 +1,303 @@
<?php
namespace App\Support;
class Address
{
/* @var ?string */
public ?string $street;
/* @var ?string */
public ?string $unit;
/* @var ?string */
public ?string $city;
/* @var ?string */
public ?string $state;
/* @var ?string */
public ?string $postalCode;
/* @var ?string */
public ?string $country;
/**
* The Address helpser constructor.
*
* @since 1.0.0
*
* @param array $inputs
*
* @return void
*/
public function __construct(array $inputs): void
{
$this->processAddress($inputs);
}
/**
* Process user inputs to our Address object.
*
* @since 1.0.0
*
* @param array $inputs
*
* @return void
*/
public function processAddress(array $inputs): void
{
// TODO: attempt to determine how the address is formulated
// could be just numerical indexed, or could be
// named keys but not sure of names
$this->street = $this->resolveStreet($inputs);
}
/*
|--------------------------------------------------------------------------
| Helpers
|--------------------------------------------------------------------------
|
*/
/**
* Attempt to determine what the street address
* is in the given data.
*
* @since 1.0.0
*
* @param array $inputs
*
* @return string|null
*/
private function resolveStreet(array $inputs): ?string
{
$street = '';
if (array_key_exists('street', $inputs)) {
$street = $inputs['street'];
} elseif (array_key_exists('street_1', $inputs)) {
$street = $inputs['street_1'];
} elseif (array_key_exists('street_address', $inputs)) {
$street = $inputs['street_address'];
} elseif (array_key_exists('line_1', $inputs)) {
$street = $inputs['line_1'];
} elseif (! empty($inputs[0])) {
$street = $inputs[0];
} elseif (array_key_exists('0', $inputs)) {
$street = $inputs['0'];
}
if (empty($street)) {
$street = null;
}
return $street;
}
/**
* Attempt to determine what the street address
* unit is in the given data.
*
* @since 1.0.0
*
* @param array $inputs
*
* @return string|null
*/
private function resolveUnit(array $inputs): ?string
{
$unit = null;
if (array_key_exists('unit', $inputs)) {
$unit = $inputs['unit'];
} elseif (array_key_exists('street_2', $inputs)) {
$unit = $inputs['street_2'];
} elseif (array_key_exists('line_2', $inputs)) {
$unit = $inputs['line_2'];
} elseif (! empty($inputs[1])) {
$unit = $inputs[1];
} elseif (array_key_exists('1', $inputs)) {
$unit = $inputs['1'];
}
if (empty($unit)) {
$unit = null;
}
return $unit;
}
/**
* Attempt to determine what the city is in the given data.
*
* @since 1.0.0
*
* @param array $inputs
*
* @return string|null
*/
private function resolveCity(array $inputs): ?string
{
$city = '';
if (array_key_exists('city', $inputs)) {
$city = $inputs['city'];
} elseif (array_key_exists(2, $inputs)) {
$city = $inputs[2];
} elseif (array_key_exists('2', $inputs)) {
$city = $inputs['2'];
}
if (empty($city)) {
$city = null;
}
return $city;
}
/**
* Attempt to determine what the state is in the given data.
*
* @since 1.0.0
*
* @param array $inputs
*
* @return string|null
*/
private function resolveState(array $inputs): ?string
{
$numericKey = 3;
if (empty($this->unit)) {
$numericKey--;
}
$state = '';
if (array_key_exists('state', $inputs)) {
$state = $inputs['state'];
} elseif (array_key_exists('st', $inputs)) {
$state = $inputs['st'];
} elseif (array_key_exists($numericKey, $inputs)) {
$state = $inputs[$numericKey];
} elseif (array_key_exists("$numericKey", $inputs)) {
$state = $inputs["$numericKey"];
}
if (empty($state)) {
$state = null;
}
return $state;
}
/**
* Attempt to determine what the postal code is in the given data.
*
* @since 1.0.0
*
* @param array $inputs
*
* @return string|null
*/
private function resolvePostalCode(array $inputs): ?string
{
$numericKey = 4;
if (empty($this->unit)) {
$numericKey--;
}
$postalCode = '';
if (array_key_exists('postal_code', $inputs)) {
$postalCode = $inputs['postal_code'];
} elseif (array_key_exists('postalCode', $inputs)) {
$postalCode = $inputs['postalCode'];
} elseif (array_key_exists('postal', $inputs)) {
$postalCode = $inputs['postal'];
} elseif (array_key_exists('zipcode', $inputs)) {
$postalCode = $inputs['zipcode'];
} elseif (array_key_exists('zip_code', $inputs)) {
$postalCode = $inputs['zip_code'];
} elseif (array_key_exists('zipCode', $inputs)) {
$postalCode = $inputs['zipCode'];
} elseif (array_key_exists('zip', $inputs)) {
$postalCode = $inputs['zip'];
} elseif (array_key_exists($numericKey, $inputs)) {
$postalCode = $inputs[$numericKey];
} elseif (array_key_exists("$numericKey", $inputs)) {
$postalCode = $inputs["$numericKey"];
}
if (empty($postalCode)) {
$postalCode = null;
}
return $postalCode;
}
/**
* Attempt to determine what the country is in the given data.
*
* @since 1.0.0
*
* @param array $inputs
*
* @return string|null
*/
private function resolveCountry(array $inputs): ?string
{
$numericKey = 5;
if (empty($this->unit)) {
$numericKey--;
}
$country = '';
if (array_key_exists('country', $inputs)) {
$country = $inputs['country'];
} elseif (array_key_exists('st', $inputs)) {
$country = $inputs['st'];
} elseif (array_key_exists($numericKey, $inputs)) {
$country = $inputs[$numericKey];
} elseif (array_key_exists("$numericKey", $inputs)) {
$country = $inputs["$numericKey"];
}
if (empty($country)) {
$country = null;
}
return $country;
}
/**
* Magic method to convert this object to a string.
*
* @since 1.0.0
*
* @return string
*/
public function __toString(): string
{
$fullAddress = $this->street;
if (! empty($this->unit)) {
$fullAddress .= " {$this->unit}";
}
if (! empty($this->city)) {
$fullAddress .= ", {$this->city}";
}
if (! empty($this->state)) {
$fullAddress .= ", {$this->state}";
}
if (! empty($this->postalCode)) {
$fullAddress .= $this->postalCode;
}
if (! empty($this->country)) {
$fullAddress .= ", {$this->country}";
}
return $fullAddress;
}
}

18
src/composer.json Normal file
View File

@ -0,0 +1,18 @@
{
//...
"autoload": {
//...
"files": [
"helpers/constants/cache_ttl.php",
"helpers/constants/http_status_codes.php",
"helpers/global_functions.php"
]
},
//...
"scripts": {
"post-autoload-dump": [
//...
"@php artisan ziggy:generate --ansi"
],
},
}

View File

@ -22,12 +22,13 @@ class CreateAddressesTable extends Migration
$table->string('state');
$table->string('postal_code'); // leave as string to accomodate 12345-6789 or Canada
$table->string('country')->default('United States');
$table->float('latitude', 12, 9)->index()->nullable();
$table->float('longitude', 12, 9)->index()->nullable();
$table->float('latitude', 12, 9)->nullable();
$table->float('longitude', 12, 9)->nullable();
$table->point('location')->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
$table->index(['latitude', 'longitude']);
$table->spatialIndex('location');
});
}

View File

@ -5,6 +5,10 @@ define('CACHE_TTL_FIFTEEN_MINUTES', 900);
define('CACHE_TTL_HALF_HOUR', 1800);
define('CACHE_TTL_ONE_HOUR', 3600);
define('CACHE_TTL_TWO_HOURS', 7200);
define('CACHE_TTL_THREE_HOURS', 10800);
define('CACHE_TTL_SIX_HOURS', 21600);
define('CACHE_TTL_TWELVE_HOURS', 43200);
define('CACHE_TTL_ONE_DAY', 86400);

View File

@ -17,7 +17,16 @@ if (! function_exists('snake2Title')) {
}
if (! function_exists('carbon')) {
function carbon(?string $timestring = null)
/**
* Return a Carbon object based on a given timestring.
* It will attempt to find a timezone in the current
* session but default to UTC.
*
* @param string|null $timestring
*
* @return \Carbon\Carbon
*/
function carbon(?string $timestring = null): \Carbon\Carbon
{
$carbon = Carbon\Carbon::now(session('timezone_name'));
if (! empty($timestring)) {
@ -28,7 +37,15 @@ if (! function_exists('carbon')) {
}
if (! function_exists('jddayofweek')) {
function jddayofweek(?int $intDay = null, int $mode = 0)
/**
* Returns the day of the week. Can return a string or an integer depending on the mode.
*
* @param int|null $intDay
* @param int $mode
*
* @return string
*/
function jddayofweek(?int $intDay = null, int $mode = 0): string
{
if (is_null($intDay)) {
$intDay = date('l');
@ -41,3 +58,108 @@ if (! function_exists('jddayofweek')) {
return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][$intDay];
}
}
if (! function_exists('cel2Fah')) {
/**
* Convert from celsius to fahrenheit.
*
* @param float|int|string $celsius
* @param int $precision
*
* @return float
*/
function cel2Fah($celsius, int $preceision = 0): float
{
return round((($celsius * (9/5)) + 32), $preceision);
}
}
if (! function_exists('fah2Cel')) {
/**
* Convert from fahrenheit to celsius.
*
* @param float|int|string $fahrenheit
* @param int $precision
*
* @return float
*/
function fah2Cel($fahrenheit, int $preceision = 1): float
{
return round(($fahrenheit - 32 * (5/9)), $preceision);
}
}
if (! function_exists('meters2Miles')) {
/**
* Convert from meters to miles.
*
* @param float|int|string $meters
* @param int $precision
*
* @return float
*/
function meters2Miles($meters, int $preceision = 1): float
{
return round(($meters * 0.00062137), $preceision);
}
}
if (! function_exists('kilometers2Miles')) {
/**
* Convert from kilometers to meters.
*
* @param float|int|string $kilometers
* @param int $precision
*
* @return float
*/
function kilometers2Miles($kilometers, int $preceision = 1): float
{
return round(($kilometers * 1.609), $preceision);
}
}
if (! function_exists('m2Km')) {
/**
* Convert from meters to kilometers.
*
* @param float|int|string $meters
* @param int $precision
*
* @return float
*/
function m2Km($meters, int $preceision = 1): float
{
return round(($meters / 1000), $preceision);
}
}
if (! function_exists('mm2Inches')) {
/**
* Convert from milimeters to inches.
*
* @param float|int|string $milimeters
* @param int $precision
*
* @return float
*/
function mm2Inches($milimeters, int $preceision = 1): float
{
return round(($milimeters / 25.4), $preceision);
}
}
if (! function_exists('pa2Mbar')) {
/**
* Convert from pascals to milibars.
*
* @param float|int|string $pascals
* @param int $precision
*
* @return float
*/
function pa2Mbar($pascals, int $preceision = 1): float
{
return round(($pascals / 100), $preceision);
}
}

View File

@ -1,5 +1,5 @@
.card {
@apply flex flex-col nm-flat-white dark:nm-flat-gray-700 border border-gray-100 dark:border-gray-800 overflow-hidden rounded-lg;
@apply flex flex-col bg-white dark:bg-zinc-700 border border-gray-100 dark:border-gray-800 overflow-hidden rounded-lg;
}
.card .card-header {

View File

@ -25,7 +25,7 @@
</template>
<script>
import { defineComponent } from 'vue'
import { defineComponent, ref } from 'vue'
export default defineComponent({
props: {
@ -35,10 +35,10 @@ export default defineComponent({
},
},
data() {
return {
show: false,
}
setup(props) {
let show = ref(false)
return { show }
},
mounted() {

View File

@ -0,0 +1,50 @@
<template>
<NotificationGroup group="error">
<div class="fixed inset-0 flex items-start justify-end p-6 px-4 py-6 pointer-events-none z-50">
<div class="w-full max-w-sm">
<Notification
v-slot="{ notifications }"
enter="transform ease-out duration-300 transition"
enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-4"
enter-to="translate-y-0 opacity-100 sm:translate-x-0"
leave="transition ease-in duration-500"
leave-from="opacity-100"
leave-to="opacity-0"
move="transition duration-500"
move-delay="delay-300"
>
<div class="flex w-full max-w-sm mx-auto mt-4 overflow-hidden bg-white rounded-lg shadow-md border border-gray-200"
v-for="notification in notifications"
:key="notification.id"
>
<div class="flex items-center justify-center w-12 bg-red-500">
<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="w-6 h-6 text-white">
<polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon>
<line x1="15" y1="9" x2="9" y2="15"></line>
<line x1="9" y1="9" x2="15" y2="15"></line>
</svg>
</div>
<div class="px-4 py-2 -mx-3">
<div class="mx-3">
<span class="font-semibold text-red-500">{{ notification.title }}</span>
<p class="text-sm text-gray-600">{{ notification.text }}</p>
</div>
</div>
</div>
</Notification>
</div>
</div>
</NotificationGroup>
</template>
<script>
import { defineComponent } from 'vue'
import Notifications from 'notiwind'
export default defineComponent({
components: {
Notifications,
},
})
</script>

View File

@ -0,0 +1,48 @@
<template>
<NotificationGroup group="generic">
<div class="fixed inset-0 flex items-start justify-end p-6 px-4 py-6 pointer-events-none z-50">
<div class="w-full max-w-sm">
<Notification
v-slot="{ notifications }"
enter="transform ease-out duration-300 transition"
enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-4"
enter-to="translate-y-0 opacity-100 sm:translate-x-0"
leave="transition ease-in duration-500"
leave-from="opacity-100"
leave-to="opacity-0"
move="transition duration-500"
move-delay="delay-300"
>
<div class="flex w-full max-w-sm mx-auto mt-4 overflow-hidden bg-white rounded-lg shadow-md border border-gray-200"
v-for="notification in notifications"
:key="notification.id"
>
<div class="flex items-center justify-center w-12 bg-gray-500">
<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="w-6 h-6 text-white">
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline>
</svg>
</div>
<div class="px-4 py-2 -mx-3">
<div class="mx-3">
<span class="font-semibold text-gray-500">{{ notification.title }}</span>
<p class="text-sm text-gray-600">{{ notification.text }}</p>
</div>
</div>
</div>
</Notification>
</div>
</div>
</NotificationGroup>
</template>
<script>
import { defineComponent } from 'vue'
import Notifications from 'notiwind'
export default defineComponent({
components: {
Notifications,
},
})
</script>

View File

@ -0,0 +1,48 @@
<template>
<NotificationGroup group="success">
<div class="fixed inset-0 flex items-start justify-end p-6 px-4 py-6 pointer-events-none z-50">
<div class="w-full max-w-sm">
<Notification
v-slot="{ notifications }"
enter="transform ease-out duration-300 transition"
enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-4"
enter-to="translate-y-0 opacity-100 sm:translate-x-0"
leave="transition ease-in duration-500"
leave-from="opacity-100"
leave-to="opacity-0"
move="transition duration-500"
move-delay="delay-300"
>
<div class="flex w-full max-w-sm mx-auto mt-4 overflow-hidden bg-white rounded-lg shadow-md border border-gray-200"
v-for="notification in notifications"
:key="notification.id"
>
<div class="flex items-center justify-center w-12 bg-green-500">
<svg class="w-6 h-6 text-white fill-current" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
<path d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM16.6667 28.3333L8.33337 20L10.6834 17.65L16.6667 23.6166L29.3167 10.9666L31.6667 13.3333L16.6667 28.3333Z" />
</svg>
</div>
<div class="px-4 py-2 -mx-3">
<div class="mx-3">
<span class="font-semibold text-green-500">{{ notification.title }}</span>
<p class="text-sm text-gray-600">{{ notification.text }}</p>
</div>
</div>
</div>
</Notification>
</div>
</div>
</NotificationGroup>
</template>
<script>
import { defineComponent } from 'vue'
import Notifications from 'notiwind'
export default defineComponent({
components: {
Notifications,
},
})
</script>

View File

@ -0,0 +1,48 @@
<template>
<NotificationGroup group="warning">
<div class="fixed inset-0 flex items-start justify-end p-6 px-4 py-6 pointer-events-none z-50">
<div class="w-full max-w-sm">
<Notification
v-slot="{ notifications }"
enter="transform ease-out duration-300 transition"
enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-4"
enter-to="translate-y-0 opacity-100 sm:translate-x-0"
leave="transition ease-in duration-500"
leave-from="opacity-100"
leave-to="opacity-0"
move="transition duration-500"
move-delay="delay-300"
>
<div class="flex w-full max-w-sm mx-auto mt-4 overflow-hidden bg-white rounded-lg shadow-md border border-gray-200"
v-for="notification in notifications"
:key="notification.id"
>
<div class="flex items-center justify-center w-12 bg-orange-500">
<svg class="w-6 h-6 text-white fill-current" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
<path d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM16.6667 28.3333L8.33337 20L10.6834 17.65L16.6667 23.6166L29.3167 10.9666L31.6667 13.3333L16.6667 28.3333Z" />
</svg>
</div>
<div class="px-4 py-2 -mx-3">
<div class="mx-3">
<span class="font-semibold text-orange-500">{{ notification.title }}</span>
<p class="text-sm text-gray-600">{{ notification.text }}</p>
</div>
</div>
</div>
</Notification>
</div>
</div>
</NotificationGroup>
</template>
<script>
import { defineComponent } from 'vue'
import Notifications from 'notiwind'
export default defineComponent({
components: {
Notifications,
},
})
</script>

View File

@ -46,7 +46,7 @@ export default defineComponent({
"transition",
]
let tiveClasses = [
let activeClasses = [
"border-transparent",
"text-gray-600",
"hover:text-gray-800",
@ -58,7 +58,7 @@ export default defineComponent({
]
if (props.active) {
tiveClasses = [
activeClasses = [
"border-indigo-400",
"text-indigo-700",
"bg-indigo-50",
@ -68,7 +68,7 @@ export default defineComponent({
]
}
defaultClasses = dClasses.concat(tiveClasses)
defaultClasses = dClasses.concat(activeClasses)
for (let elm of props.class.split(" ")) {
elm = elm.trim()

View File

@ -44,20 +44,20 @@ export default defineComponent({
"rounded-lg",
]
let tiveClasses = [
"nm-flat-white",
"hover:nm-concave-blue-300",
let activeClasses = [
"bg-white",
"hover:bg-blue-300",
"hover:text-white",
]
if (props.active) {
tiveClasses = [
"nm-flat-blue-400",
activeClasses = [
"bg-blue-400",
"text-white",
]
}
defaultClasses = dClasses.concat(tiveClasses)
defaultClasses = dClasses.concat(activeClasses)
for (let elm of props.class.split(" ")) {
elm = elm.trim()

View File

@ -3,9 +3,10 @@
<Head :title="title" />
<div class="absolute top-0 mt-4 z-50">
<success-notifications />
<error-notifications />
<generic-notifications />
<generic-notifications></generic-notifications>
<success-notifications></success-notifications>
<warning-notifications></warning-notifications>
<error-notifications></error-notifications>
</div>
<jet-banner />
@ -206,10 +207,6 @@
Profile
</jet-dropdown-link>
<jet-dropdown-link :href="route('profile.billing.show')">
Billing
</jet-dropdown-link>
<jet-dropdown-link :href="route('api-tokens.index')" v-if="$page.props.jetstream.hasApiFeatures">
API Tokens
</jet-dropdown-link>
@ -237,17 +234,17 @@
</template>
<script>
import { defineComponent } from "vue"
import { Head, Link } from "@inertiajs/inertia-vue3"
import SuccessNotifications from "@/Components/Notifications/SuccessNotifications.vue"
import ErrorNotifications from "@/Components/Notifications/ErrorNotifications.vue"
import GenericNotifications from "@/Components/Notifications/GenericNotifications.vue"
import ApplicationMark from "@/Jetstream/ApplicationMark.vue"
import ResponsiveNavLink from "@/Components/ResponsiveNavLink.vue"
import SidenavLink from "@/Components/SidenavLink.vue"
import JetBanner from "@/Jetstream/Banner.vue"
import JetDropdown from "@/Jetstream/Dropdown.vue"
import JetDropdownLink from "@/Jetstream/DropdownLink.vue"
import { defineComponent, ref } from 'vue'
import { Head, Link } from '@inertiajs/inertia-vue3'
import SuccessNotifications from '@/Components/Notifications/SuccessNotifications.vue'
import ErrorNotifications from '@/Components/Notifications/ErrorNotifications.vue'
import GenericNotifications from '@/Components/Notifications/GenericNotifications.vue'
import ApplicationMark from '@/Jetstream/ApplicationMark.vue'
import ResponsiveNavLink from '@/Components/ResponsiveNavLink.vue'
import SidenavLink from '@/Components/SidenavLink.vue'
import JetBanner from '@/Jetstream/Banner.vue'
import JetDropdown from '@/Jetstream/Dropdown.vue'
import JetDropdownLink from '@/Jetstream/DropdownLink.vue'
export default defineComponent({
props: {
@ -268,23 +265,23 @@ export default defineComponent({
JetDropdownLink,
},
data() {
return {
showingNavigationDropdown: false,
}
setup(props) {
let showingNavigationDropdown = ref(false)
return { showingNavigationDropdown }
},
methods: {
switchToTeam(team) {
this.$inertia.put(route("current-team.update"), {
"team_id": team.id
this.$inertia.put(route('current-team.update'), {
'team_id': team.id
}, {
preserveState: false
})
},
logout() {
this.$inertia.post(route("logout"));
this.$inertia.post(route('logout'));
},
}
})

View File

@ -9,11 +9,13 @@
</template>
<script>
import { defineComponent } from "vue"
import AppLayout from "@/Layouts/AppLayout.vue"
import Card from "@/Components/Card.vue"
import { defineComponent, reactive, ref, computed, watch, onBeforeMount, onMounted, provide, inject } from 'vue'
import AppLayout from '@/Layouts/AppLayout.vue'
import Card from '@/Components/Card.vue'
export default defineComponent({
emits: [],
props: {},
components: {
@ -21,16 +23,38 @@ export default defineComponent({
Card,
},
data() {
return {}
setup(props, { attrs, slots, emit, expose }) {
let aVariable = reactive({})
// computed properties
/*let compVariable = computed(() => {
//return 'foo'
})*/
// watchers
/*watch(aVariable, (newValue, oldValue) => {
//
})*/
// lifecycle hooks
onBeforeMount(() => {
//
})
onMounted(() => {
//
})
// methods
function myMethod() {
aVariable.value = null
}
return {
aVariable,
compVariable,
myMethod,
}
},
setup(props) {
return {}
},
computed: {},
methods: {},
})
</script>

55
src/webpack.mix.js Normal file
View File

@ -0,0 +1,55 @@
const mix = require('laravel-mix');
const { exec } = require('child_process');
const shaCmd = "cat public/js/app.js | openssl dgst -sha512 -binary | openssl base64 -A";
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel applications. By default, we are compiling the CSS
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/js/app.js', 'public/js')
.vue()
.sourceMaps()
.after(stats => {
exec(shaCmd, (shaError, shaStdout, shaStderr) => {
if (shaError) {
console.error(`shaCmd error: ${shaError.message}`);
return;
}
if (shaStderr) {
console.error(`shaCmd stderr: ${shaStderr}`);
return;
}
let sha512Hash = shaStdout;
let sedCmd = `sed -i '/^APP_JS_INTEGRITY_HASH="*/c\APP_JS_INTEGRITY_HASH="sha512-${sha512Hash}"' .env`;
exec(sedCmd, (sedError, sedStdout, sedStderr) => {
if (sedError) {
console.error(`sedCmd error: ${sedError.message}`);
return;
}
if (sedStderr) {
console.error(`sedCmd stderr: ${sedStderr}`);
return;
}
console.log('Replaced SHA512 hash for integrity attribute.');
})
})
})
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
])
.sourceMaps()
.webpackConfig(require('./webpack.config'));
if (mix.inProduction()) {
mix.version();
}