Added Notifications
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ use App\Traits\HasAchievements;
|
|||||||
use App\Models\Notification;
|
use App\Models\Notification;
|
||||||
use Laravel\Sanctum\HasApiTokens;
|
use Laravel\Sanctum\HasApiTokens;
|
||||||
|
|
||||||
#[Fillable(['name', 'email', 'password'])]
|
#[Fillable(['name', 'email', 'password', 'distance_unit'])]
|
||||||
#[Hidden(['password', 'remember_token'])]
|
#[Hidden(['password', 'remember_token'])]
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?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::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('distance_unit', 3)->default('km')->after('id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -7,6 +7,7 @@ import GlassTooltip from "@/Components/FlightsGoneBy/GlassTooltip.vue";
|
|||||||
import {Link} from '@inertiajs/vue3'
|
import {Link} from '@inertiajs/vue3'
|
||||||
import ButtonLink from "@/Components/FlightsGoneBy/ButtonLink.vue";
|
import ButtonLink from "@/Components/FlightsGoneBy/ButtonLink.vue";
|
||||||
import Distance from "@/Components/Distance.vue";
|
import Distance from "@/Components/Distance.vue";
|
||||||
|
import FormattedNumber from "@/Components/FormattedNumber.vue";
|
||||||
|
|
||||||
const distanceAchievements = [
|
const distanceAchievements = [
|
||||||
'general_flying.circumference_of_the_earth',
|
'general_flying.circumference_of_the_earth',
|
||||||
@@ -18,6 +19,7 @@ const props = defineProps<{
|
|||||||
achievement: Achievement
|
achievement: Achievement
|
||||||
userAchievement?: UserAchievement
|
userAchievement?: UserAchievement
|
||||||
user?: User
|
user?: User
|
||||||
|
distanceUnit? : "mi" | "km" | "nm"
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const progress = computed(() => {
|
const progress = computed(() => {
|
||||||
@@ -101,7 +103,14 @@ const difficultyVariant = computed(() => {
|
|||||||
|
|
||||||
<template v-if="achievement.progressive && progress">
|
<template v-if="achievement.progressive && progress">
|
||||||
<div class="progress-label">
|
<div class="progress-label">
|
||||||
<span><distance :showUnits="false" :value="Math.min(progress.current, progress.threshold)" /> / <distance :value="progress.threshold" :showUnits="distanceAchievements.includes(achievement.internal_name)" /></span>
|
<span v-if="distanceAchievements.includes(achievement.internal_name)">
|
||||||
|
<Distance :unit="distanceUnit" :showUnits="false" :value="Math.min(progress.current, progress.threshold)" /> /
|
||||||
|
<Distance :unit="distanceUnit" :value="progress.threshold" />
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
<FormattedNumber :value="Math.min(progress.current, progress.threshold)" /> /
|
||||||
|
<FormattedNumber :value="progress.threshold" />
|
||||||
|
</span>
|
||||||
<span>{{ progress.percentage }}%</span>
|
<span>{{ progress.percentage }}%</span>
|
||||||
</div>
|
</div>
|
||||||
<v-progress-linear
|
<v-progress-linear
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {Flight, User} from "@/Types/types";
|
import {Flight, SharedProps, User} from "@/Types/types";
|
||||||
import AirlineLogo from "@/Components/FlightsGoneBy/AirlineLogo.vue";
|
import AirlineLogo from "@/Components/FlightsGoneBy/AirlineLogo.vue";
|
||||||
import AirportToolTip from "@/Components/FlightsGoneBy/AirportToolTip.vue";
|
import AirportToolTip from "@/Components/FlightsGoneBy/AirportToolTip.vue";
|
||||||
import AircraftToolTip from "@/Components/FlightsGoneBy/AircraftToolTip.vue";
|
import AircraftToolTip from "@/Components/FlightsGoneBy/AircraftToolTip.vue";
|
||||||
import Distance from "@/Components/Distance.vue";
|
import Distance from "@/Components/Distance.vue";
|
||||||
import UserFlightContextMenu from "@/Components/FlightsGoneBy/UserFlightContextMenu.vue";
|
import UserFlightContextMenu from "@/Components/FlightsGoneBy/UserFlightContextMenu.vue";
|
||||||
|
import {usePage} from "@inertiajs/vue3";
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
flight: Flight
|
flight: Flight
|
||||||
@@ -13,6 +14,7 @@ defineProps<{
|
|||||||
user?: User
|
user?: User
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const page = usePage<SharedProps>().props
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -75,7 +77,7 @@ defineProps<{
|
|||||||
<span class="pass-stat-divider" v-if="flight.duration_display && flight.distance">·</span>
|
<span class="pass-stat-divider" v-if="flight.duration_display && flight.distance">·</span>
|
||||||
<span v-if="flight.distance" class="pass-stat">
|
<span v-if="flight.distance" class="pass-stat">
|
||||||
<span class="pass-stat-label">DISTANCE</span>
|
<span class="pass-stat-label">DISTANCE</span>
|
||||||
<span class="pass-stat-value"><Distance :value="Math.round(flight.distance)" /></span>
|
<span class="pass-stat-value"><Distance :unit="page.auth?.user?.distance_unit" :value="Math.round(flight.distance)" /></span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import FlightClassBadge from "@/Components/FlightsGoneBy/FlightClassBadge.vue";
|
import FlightClassBadge from "@/Components/FlightsGoneBy/FlightClassBadge.vue";
|
||||||
import AirlineLogo from "@/Components/FlightsGoneBy/AirlineLogo.vue";
|
import AirlineLogo from "@/Components/FlightsGoneBy/AirlineLogo.vue";
|
||||||
import {Flight, User} from "@/Types/types";
|
import {Flight, SharedProps, User} from "@/Types/types";
|
||||||
import { computed, ref, watch, nextTick } from "vue";
|
import { computed, ref, watch, nextTick } from "vue";
|
||||||
import type { DataTableSortItem } from 'vuetify';
|
import type { DataTableSortItem } from 'vuetify';
|
||||||
import InlineBadge from "@/Components/FlightsGoneBy/InlineBadge.vue";
|
import InlineBadge from "@/Components/FlightsGoneBy/InlineBadge.vue";
|
||||||
@@ -12,6 +12,7 @@ import {FlightStats} from "@/Composables/useFlightStats";
|
|||||||
import CrewTooltip from "@/Components/FlightsGoneBy/CrewTooltip.vue";
|
import CrewTooltip from "@/Components/FlightsGoneBy/CrewTooltip.vue";
|
||||||
import Distance from "@/Components/Distance.vue";
|
import Distance from "@/Components/Distance.vue";
|
||||||
import UserFlightContextMenu from "@/Components/FlightsGoneBy/UserFlightContextMenu.vue";
|
import UserFlightContextMenu from "@/Components/FlightsGoneBy/UserFlightContextMenu.vue";
|
||||||
|
import {usePage} from "@inertiajs/vue3";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
flightStats: FlightStats
|
flightStats: FlightStats
|
||||||
@@ -64,6 +65,7 @@ const customKeySort = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const page = usePage<SharedProps>()
|
||||||
|
|
||||||
const sortBy = ref<DataTableSortItem[]>([])
|
const sortBy = ref<DataTableSortItem[]>([])
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
@@ -226,7 +228,7 @@ watch(
|
|||||||
|
|
||||||
<td class="v-data-table__td">
|
<td class="v-data-table__td">
|
||||||
<span class="mono-tag distance-cell">
|
<span class="mono-tag distance-cell">
|
||||||
<Distance :value="Math.round((item as Flight).distance)" />
|
<Distance :unit="page.props.auth.user?.distance_unit" :value="Math.round((item as Flight).distance)" />
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|||||||
@@ -35,12 +35,12 @@
|
|||||||
<div class="stat">
|
<div class="stat">
|
||||||
<template v-if="totalDistanceKm">
|
<template v-if="totalDistanceKm">
|
||||||
<div class="stat-primary">
|
<div class="stat-primary">
|
||||||
<span class="stat-num"><Distance includeSpace :value="totalDistanceKm" /></span>
|
<span class="stat-num"><Distance :unit="page.auth?.user?.distance_unit" includeSpace :value="totalDistanceKm" /></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="upcomingDistanceKm">
|
<template v-if="upcomingDistanceKm">
|
||||||
<div :class="totalDistanceKm ? 'stat-upcoming' : 'stat-primary'">
|
<div :class="totalDistanceKm ? 'stat-upcoming' : 'stat-primary'">
|
||||||
<span :class="totalDistanceKm ? 'stat-upcoming-num' : 'stat-num'"><Distance includeSpace :value="upcomingDistanceKm"/></span>
|
<span :class="totalDistanceKm ? 'stat-upcoming-num' : 'stat-num'"><Distance :unit="page.auth?.user?.distance_unit" includeSpace :value="upcomingDistanceKm"/></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,14 +99,17 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import type { Flight } from '@/Types/types'
|
import type {Flight, SharedProps} from '@/Types/types'
|
||||||
import Distance from "@/Components/Distance.vue";
|
import Distance from "@/Components/Distance.vue";
|
||||||
|
import {usePage} from "@inertiajs/vue3";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
flights: Flight[]
|
flights: Flight[]
|
||||||
upcomingFlights: Flight[]
|
upcomingFlights: Flight[]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const page = usePage<SharedProps>().props
|
||||||
|
|
||||||
// ── Past ──────────────────────────────────────────────────────────────────────
|
// ── Past ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
const totalDistanceKm = computed(() =>
|
const totalDistanceKm = computed(() =>
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { ref, computed } from "vue"
|
|||||||
import ProfileLayout from "@/Components/FlightsGoneBy/ProfileLayout.vue"
|
import ProfileLayout from "@/Components/FlightsGoneBy/ProfileLayout.vue"
|
||||||
import ProfileViewSwitcher from "@/Components/FlightsGoneBy/ProfileViewSwitcher.vue"
|
import ProfileViewSwitcher from "@/Components/FlightsGoneBy/ProfileViewSwitcher.vue"
|
||||||
import AchievementCard from "@/Components/FlightsGoneBy/AchievementCard.vue"
|
import AchievementCard from "@/Components/FlightsGoneBy/AchievementCard.vue"
|
||||||
import {Achievement, User, UserAchievement} from "@/Types/types"
|
import {Achievement, SharedProps, User, UserAchievement} from "@/Types/types"
|
||||||
import { Head } from "@inertiajs/vue3";
|
import {Head, usePage} from "@inertiajs/vue3";
|
||||||
import MainLayout from "@/Layouts/MainLayout.vue";
|
import MainLayout from "@/Layouts/MainLayout.vue";
|
||||||
import Panel from "@/Components/FlightsGoneBy/Panels/Panel.vue";
|
import Panel from "@/Components/FlightsGoneBy/Panels/Panel.vue";
|
||||||
import PanelHeader from "@/Components/FlightsGoneBy/Panels/PanelHeader.vue";
|
import PanelHeader from "@/Components/FlightsGoneBy/Panels/PanelHeader.vue";
|
||||||
@@ -22,6 +22,8 @@ const props = defineProps<{
|
|||||||
unlockedByCategory: Record<string, number>
|
unlockedByCategory: Record<string, number>
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const page = usePage<SharedProps>().props
|
||||||
|
|
||||||
const hideImpossible = ref(false)
|
const hideImpossible = ref(false)
|
||||||
|
|
||||||
const filteredAchievements = computed(() => {
|
const filteredAchievements = computed(() => {
|
||||||
@@ -105,6 +107,7 @@ const filteredUnlockedCount = computed(() =>
|
|||||||
:key="achievement.id"
|
:key="achievement.id"
|
||||||
:achievement="achievement"
|
:achievement="achievement"
|
||||||
:user-achievement="userAchievements[achievement.id]"
|
:user-achievement="userAchievements[achievement.id]"
|
||||||
|
:distance-unit="page.auth?.user?.distance_unit"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|||||||
Vendored
+1
@@ -17,6 +17,7 @@ export interface User {
|
|||||||
name: string
|
name: string
|
||||||
email: string
|
email: string
|
||||||
email_verified_at: string | null
|
email_verified_at: string | null
|
||||||
|
distance_unit: "km" | "mi" | "nm"
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UserActionType = "flight_cancelled" | "flight_booked" | "flight_updated" | "flight_logged" | "flight_deleted" | "flight_imported" | "flight_departing" | "flight_arriving"
|
export type UserActionType = "flight_cancelled" | "flight_booked" | "flight_updated" | "flight_logged" | "flight_deleted" | "flight_imported" | "flight_departing" | "flight_arriving"
|
||||||
|
|||||||
Reference in New Issue
Block a user