Status Update

Major status update
This commit is contained in:
Trenton Zimmer
2023-07-07 09:27:46 -04:00
parent ed10aaf710
commit cd960068f0
46 changed files with 826 additions and 264 deletions

View File

@@ -8,13 +8,14 @@
<title>PhaseWeb 3</title>
</head>
<body>
<body class="scroll-smooth">
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
<!-- built files will be auto injected -->
<audio id="audio" src="/assets/sounds/konami.mp3" class="hidden" />
</body>
<style>
@@ -28,4 +29,27 @@
}
}
</style>
<script>
var pattern = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
var current = 0;
var keyHandler = function (event) {
if (pattern.indexOf(event.key) < 0 || event.key !== pattern[current]) {
current = 0;
return;
}
current++;
if (pattern.length === current) {
current = 0;
document.getElementById('audio').play();
window.alert('+30 lives.');
}
};
document.addEventListener('keydown', keyHandler, false);
</script>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

View File

@@ -0,0 +1,55 @@
<script setup>
import { mdiCog } from "@mdi/js";
import CardBoxWidget from "@/components/CardBoxWidget.vue";
import BaseButton from "@/components/BaseButton.vue";
defineProps({
useQpro: {
type: Boolean,
default: false,
},
avatar: {
type: String,
default: null,
},
useSmall: {
type: Boolean,
default: false,
},
});
var last = {
arcade: "Ho-House",
};
</script>
<template>
<div class="flex justify-center items-center">
<img v-if="avatar" class="h-40" :src="avatar" />
<div class="space-y-2 text-left lg:mx-12 p-2">
<h1 class="text-3xl md:text-4xl font-bold">TRMAZI</h1>
<p class="text-xl ordinal slashed-zero">1234-5678</p>
<p class="text-md md:text-lg">
Last played at <b>{{ last.arcade }}</b> on <b>10/22/2022</b>
</p>
<BaseButton
v-if="!useSmall"
:icon="mdiCog"
href="/#/games/ddr/profiles/1"
color="info"
label="Edit Profile"
/>
</div>
</div>
<div v-if="!useSmall" class="grid grid-cols-1 gap-6 lg:grid-cols-4 pt-6">
<CardBoxWidget :number="3733" label="Scores (All Versions)" />
<CardBoxWidget :number="1244" label="Plays (All Versions)" />
<CardBoxWidget
prefix="#"
:number="43"
suffix=" / 300"
label="Ranking (All Versions)"
/>
<CardBoxWidget :number="2" label="Rivals" />
</div>
</template>

View File

@@ -137,7 +137,7 @@ if (props.ctrlKFocus) {
<option
v-for="option in options"
:key="option.id ?? option"
:value="option"
:value="option.id ?? option"
>
{{ option.label ?? option }}
</option>

View File

@@ -0,0 +1,27 @@
<script setup>
import BaseLevel from "@/components/BaseLevel.vue";
import CardBox from "@/components/CardBox.vue";
const props = defineProps({
icon: {
type: String,
required: true,
},
card: {
type: String,
required: true,
},
});
function getCardStyle() {
return `
background-image: url('${props.card}');
background-size: cover;
background-repeat: no-repeat;
`;
}
</script>
<template>
</template>

View File

@@ -23,7 +23,7 @@ const spanClass = computed(
<template>
<span :class="spanClass">
<img :src="path" class="rounded-full" :class="w + ' ' + h" />
<img :src="path" class="rounded-full" :class="`${w}`" />
<slot />
</span>
</template>

View File

@@ -0,0 +1,29 @@
<script setup>
import { useSlots, computed } from "vue";
import GameIcon from "./GameIcon.vue";
defineProps({
path: {
type: String,
default: null,
},
title: {
type: String,
required: true,
},
});
const hasSlot = computed(() => useSlots().default);
</script>
<template>
<section class="pt-6 mb-6 flex items-center justify-between">
<div class="flex items-center justify-start space-x-2">
<GameIcon :path="path" class="w-12 h-12 p-1 drop-shadow-md" />
<h1 class="text-2xl md:text-3xl leading-tight">
{{ title }}
</h1>
</div>
<slot v-if="hasSlot" />
</section>
</template>

View File

@@ -0,0 +1,77 @@
<script setup>
import { computed, ref } from "vue";
import { useMainStore } from "@/stores/main";
import BaseLevel from "@/components/BaseLevel.vue";
import BaseButtons from "@/components/BaseButtons.vue";
import BaseButton from "@/components/BaseButton.vue";
const mainStore = useMainStore();
const items = computed(() => mainStore.clients);
const perPage = ref(5);
const currentPage = ref(0);
const itemsPaginated = computed(() =>
items.value.slice(
perPage.value * currentPage.value,
perPage.value * (currentPage.value + 1)
)
);
const numPages = computed(() => Math.ceil(items.value.length / perPage.value));
const currentPageHuman = computed(() => currentPage.value + 1);
const pagesList = computed(() => {
const pagesList = [];
for (let i = 0; i < numPages.value; i++) {
pagesList.push(i);
}
return pagesList;
});
</script>
<template>
<table>
<thead>
<tr>
<th>Username</th>
<th>Rival ID</th>
<th>Creation Date</th>
<th>Last Played</th>
<th>Last Arcade</th>
<th>Play Count</th>
</tr>
</thead>
<tbody>
<tr v-for="client in itemsPaginated" :key="client.id">
<td data-label="Username">TRMAZI</td>
<td data-label="Rival ID">1234-5678</td>
<td data-label="Creation Date">10/22/2022</td>
<td data-label="Last Played">10/22/2022</td>
<td data-label="Last Arcade">Ho-House</td>
<td data-label="Play Count" class="lg:w-32">466</td>
</tr>
</tbody>
</table>
<div class="p-3 lg:px-6 border-t border-gray-100 dark:border-slate-800">
<BaseLevel>
<BaseButtons>
<BaseButton
v-for="page in pagesList"
:key="page"
:active="page === currentPage"
:label="page + 1"
:color="page === currentPage ? 'lightDark' : 'whiteDark'"
small
@click="currentPage = page"
/>
</BaseButtons>
<small>Page {{ currentPageHuman }} of {{ numPages }}</small>
</BaseLevel>
</div>
</template>

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
<script setup>
import { mdiForwardburger, mdiBackburger, mdiMenu } from "@mdi/js";
import { ref } from "vue";
import { useRouter } from "vue-router";
import { useRouter, useRoute } from "vue-router";
import menuAside from "@/menuAside.js";
import menuNavBar from "@/menuNavBar.js";
import { useMainStore } from "@/stores/main.js";
@@ -24,6 +24,7 @@ const layoutAsidePadding = "xl:pl-60";
const styleStore = useStyleStore();
const router = useRouter();
const route = useRoute();
const isAsideMobileExpanded = ref(false);
const isAsideLgActive = ref(false);
@@ -42,6 +43,7 @@ const menuClick = (event, item) => {
<template>
<div
:key="route.fullPath"
:class="{
dark: styleStore.darkMode,
'overflow-hidden lg:overflow-visible': isAsideMobileExpanded,
@@ -49,7 +51,7 @@ const menuClick = (event, item) => {
>
<div
:class="[layoutAsidePadding, { 'ml-60 lg:ml-0': isAsideMobileExpanded }]"
class="pt-14 min-h-screen w-screen transition-position lg:w-auto bg-gray-50 dark:bg-slate-800 dark:text-slate-100"
class="pt-14 min-h-screen w-screen lg:w-auto bg-gray-50 dark:bg-slate-800 dark:text-slate-100"
>
<NavBar
:menu="menuNavBar"
@@ -83,8 +85,53 @@ const menuClick = (event, item) => {
@menu-click="menuClick"
@aside-lg-close-click="isAsideLgActive = false"
/>
<slot />
<FooterBar />
<div class="animated animatedFadeInUp fadeInUp">
<slot />
<FooterBar />
</div>
</div>
</div>
</template>
<style>
/* Animation */
@keyframes fadeInUp {
from {
transform: translate3d(0, 10px, 0);
}
to {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
@-webkit-keyframes fadeInUp {
from {
transform: translate3d(0, 10px, 0);
}
to {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
.animated {
animation-duration: 0.7s;
animation-fill-mode: both;
-webkit-animation-duration: 0.7s;
-webkit-animation-fill-mode: both;
}
.animatedFadeInUp {
opacity: 0;
}
.fadeInUp {
opacity: 0;
animation-name: fadeInUp;
-webkit-animation-name: fadeInUp;
}
</style>

View File

@@ -12,13 +12,13 @@ var sortedMenu = [];
for (const game of gameData) {
if (!game.skip) {
sortedMenu.push({
label: game.name,
label: game.shortName ? game.shortName : game.name,
menu: [
{ label: "Overview", to: `/${game.id}` },
{ label: "Network Records", to: `/${game.id}/records/all` },
{ label: "Network Scores", to: `/${game.id}/scores/all` },
{ label: "Personal Records", to: `/${game.id}/records/personal` },
{ label: "Personal Scores", to: `/${game.id}/scores/personal` },
{ label: "Overview", to: `/games/${game.id}` },
{ label: "Network Records", to: `/games/${game.id}/records/all` },
{ label: "Network Scores", to: `/games/${game.id}/scores/all` },
{ label: "Personal Records", to: `/games/${game.id}/records/personal` },
{ label: "Personal Scores", to: `/games/${game.id}/scores/personal` },
],
});
}

View File

@@ -142,6 +142,28 @@ const routes = [
hotReload: true, // disables Hot Reload
},
},
{
meta: {
title: "Game Overview",
},
path: "/games/:id/",
name: "game_page",
component: () => import("@/views/Game/GameView.vue"),
options: {
hotReload: true, // disables Hot Reload
},
},
{
meta: {
title: "View Profile",
},
path: "/games/:game/profiles/:userID/",
name: "game_profile",
component: () => import("@/views/Game/PlayerView.vue"),
options: {
hotReload: true, // disables Hot Reload
},
},
{
meta: {
title: "Error",

View File

@@ -11,7 +11,7 @@ import FormField from "@/components/FormField.vue";
import FormControl from "@/components/FormControl.vue";
import FormCheckRadio from "@/components/FormCheckRadio.vue";
import BaseButton from "@/components/BaseButton.vue";
import { arcadeList, getGameTitle, getGameInfo } from "@/constants";
import { arcadeList, gameData, getGameInfo } from "@/constants";
const $route = useRoute();
const arcadeID = parseInt($route.params.id);
@@ -48,15 +48,15 @@ const eventSettings = [
options: [
{
id: 0,
name: "No Event",
label: "No Event",
},
{
id: 1,
name: "Chrono Seeker",
label: "Chrono Seeker",
},
{
id: 2,
name: "QPronicle Chord",
label: "QPronicle Chord",
},
],
value: 1,
@@ -84,33 +84,6 @@ const filterForm = reactive({
version: null,
});
function listGames() {
var games = [];
for (const object of eventSettings) {
const gameName = getGameInfo(object.game).name;
if (games[gameName] == undefined) {
games.push(gameName);
}
}
return games;
}
function listVersions() {
var versions = [];
for (const object of eventSettings) {
if (object.game == getGameInfo(filterForm.game).id) {
const gameObject = getGameInfo(object.game);
const version = object.version;
if (versions[version] == undefined) {
versions.push(gameObject.versions.find((x) => x.id == version).name);
}
}
}
return versions;
}
function getGameSettings() {
const gameObject = getGameInfo(filterForm.game);
const version = gameObject.versions.find((x) => x.name == filterForm.version);
@@ -151,7 +124,7 @@ watch(
<FormControl
v-model="filterForm.game"
name="game"
:options="listGames()"
:options="gameData"
/>
</div>
<div v-if="filterForm.game">

View File

@@ -39,10 +39,10 @@ const submit = () => {
<p class="text-sm text-gray-700 dark:text-white/75">
Spinnin' since 2021
</p>
<hr class="border-t border-1 my-1 w-full" />
<hr class="border-r-1 my-1 w-full" />
<p class="text-lg relative bottom-0">Please log in.</p>
</div>
<div class="md:border-r md:border-1"></div>
<div class="md:border-r" />
<div>
<FormField label="Username">
<FormControl
@@ -74,7 +74,7 @@ const submit = () => {
<BaseButton label="Log In" color="success" @click="submit()" />
</div>
<hr class="border-t border-1 my-4 w-full" />
<hr class="border-t my-4 w-full" />
<div class="flex flex-col gap-2 my-4">
<h2>Not Registered?</h2>

View File

@@ -0,0 +1,96 @@
<script setup>
import { reactive } from "vue";
import { useRoute, useRouter } from "vue-router";
import { mdiAccountMultiple } from "@mdi/js";
import SectionMain from "@/components/SectionMain.vue";
import SectionTitleLine from "@/components/SectionTitleLine.vue";
import GameTitleLine from "@/components/GameTitleLine.vue";
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
import CardBox from "@/components/CardBox.vue";
import FormControl from "@/components/FormControl.vue";
import ProfileCard from "@/components/Cards/ProfileCard.vue";
import TablePlayers from "@/components/Tables/TablePlayers.vue";
import { getGameInfo } from "@/constants";
const $route = useRoute();
const $router = useRouter();
var gameID = null;
var thisGame = null;
const versionForm = reactive({
currentVersion: null,
});
gameID = $route.params.id;
thisGame = getGameInfo(gameID);
if (!thisGame) {
$router.push({
name: "ErrorPage",
params: {
catchAll: "404",
},
});
}
function getSources() {
var sources = null;
if (!versionForm.currentVersion) {
sources = thisGame.cardBG;
} else {
sources = `/assets/games/${thisGame.id}/card/${versionForm.currentVersion}.png`;
}
return sources;
}
function getCardStyle() {
return `
background-image: url('${getSources()}');
background-size: cover;
background-repeat: no-repeat;
`;
}
</script>
<template>
<LayoutAuthenticated>
<SectionMain>
<div :style="getCardStyle()" class="rounded-2xl mb-6">
<div class="bg-white dark:bg-slate-900/90 rounded-2xl p-3">
<div class="w-full">
<div
class="md:flex pb-6 md:px-5 md:space-x-10 md:justify-between md:items-center"
>
<GameTitleLine :path="thisGame.icon" :title="thisGame.name" />
<div class="md:w-1/3 md:text-right">
<h2 class="text-md sm:text-lg md:text-xl font-bold p-2">
Select Version
</h2>
<FormControl
v-model="versionForm.currentVersion"
:options="thisGame.versions"
/>
</div>
</div>
</div>
<div class="w-full">
<ProfileCard
avatar="https://static.wikia.nocookie.net/dancedancerevolutionddr/images/3/3b/Yuni_img1.gif/"
/>
</div>
</div>
</div>
<SectionTitleLine :icon="mdiAccountMultiple" title="All Players" main />
<CardBox has-table>
<div
class="bg-white dark:bg-slate-900/95 rounded-2xl lg:flex lg:justify-between"
>
<div class="w-full">
<TablePlayers />
</div>
</div>
</CardBox>
</SectionMain>
</LayoutAuthenticated>
</template>

View File

@@ -0,0 +1,208 @@
<script setup>
import { reactive } from "vue";
import { useRoute, useRouter } from "vue-router";
import { mdiAccountTieHat, mdiBackburger } from "@mdi/js";
import SectionMain from "@/components/SectionMain.vue";
import CardBox from "@/components/CardBox.vue";
import BaseButton from "@/components/BaseButton.vue";
import ProfileCard from "@/components/Cards/ProfileCard.vue";
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
import SectionTitleLine from "@/components/SectionTitleLine.vue";
import GameTitleLine from "@/components/GameTitleLine.vue";
import FormField from "@/components/FormField.vue";
import FormCheckRadio from "@/components/FormCheckRadio.vue";
import FormControl from "@/components/FormControl.vue";
import { getGameInfo } from "@/constants";
const $route = useRoute();
const $router = useRouter();
var gameID = null;
var thisGame = null;
const versionForm = reactive({
currentVersion: null,
});
const settings = [
{
id: "username",
name: "Username",
help: "Set your username for this profile",
type: String,
},
{
id: "fastSlow",
name: "Fast/Slow Display",
help: "Enable or disable displaying of Fast/Slow",
type: Boolean,
},
{
id: "comboPosition",
name: "Combo Position",
help: "Change order of the combo and notes",
type: Boolean,
},
{
id: "weight",
name: "Weight (kg)",
help: "Set your weight for in-game workout mode",
type: Number,
},
{
id: "dancer",
name: "Character",
help: "Set your background dancer",
type: Array,
options: [
{ id: 0, label: "Afro" },
{ id: 1, label: "Emi" },
],
},
{
id: "arrow",
name: "Arrow Skin",
help: "Set your arrow skin",
type: Array,
options: [
{ id: 0, label: "Normal" },
{ id: 1, label: "Classic" },
],
},
];
const userSettings = reactive({
username: "TRMAZI",
fastSlow: true,
comboPosition: false,
weight: 100,
dancer: 0,
arrow: 1,
guideLines: 0,
filter: 3,
});
gameID = $route.params.game;
thisGame = getGameInfo(gameID);
if (!thisGame) {
$router.push({
name: "ErrorPage",
params: {
catchAll: "404",
},
});
}
function getSources() {
var sources = null;
if (!versionForm.currentVersion) {
sources = thisGame.cardBG;
} else {
sources = `/assets/games/${thisGame.id}/card/${versionForm.currentVersion}.png`;
}
return sources;
}
function getCardStyle() {
return `
background-image: url('${getSources()}');
background-size: cover;
background-repeat: no-repeat;
`;
}
</script>
<template>
<LayoutAuthenticated>
<SectionMain>
<div :style="getCardStyle()" class="rounded-2xl mb-6">
<div class="bg-white dark:bg-slate-900/90 rounded-2xl p-3">
<div class="w-full">
<div
class="md:flex pb-6 md:px-5 md:space-x-10 md:justify-between md:items-center"
>
<GameTitleLine :path="thisGame.icon" :title="thisGame.name" />
<div class="md:w-1/3 md:text-right">
<h2 class="text-md sm:text-lg md:text-xl font-bold p-2">
Select Version
</h2>
<FormControl
v-model="versionForm.currentVersion"
:options="thisGame.versions"
/>
</div>
</div>
</div>
<div class="w-full">
<ProfileCard
v-if="versionForm.currentVersion"
use-small
avatar="https://static.wikia.nocookie.net/dancedancerevolutionddr/images/3/3b/Yuni_img1.gif/"
/>
</div>
<BaseButton
:icon="mdiBackburger"
:href="'/#/games/' + gameID"
class="mt-2"
color="info"
label="Go Back"
/>
</div>
</div>
<SectionTitleLine
v-if="versionForm.currentVersion"
:icon="mdiAccountTieHat"
title="Profile Customizations"
main
/>
<div v-if="versionForm.currentVersion">
<CardBox>
<div>
<FormField
v-for="setting of settings"
:key="setting.id"
:label="setting.name"
:help="setting.help"
>
<FormControl
v-if="setting.type == String"
:v-model="userSettings[setting.id]"
:model-value="userSettings[setting.id]"
/>
<FormControl
v-if="setting.type == Number"
:v-model="userSettings[setting.id]"
:model-value="userSettings[setting.id]"
type="number"
/>
<FormControl
v-if="setting.type == Array"
:options="setting.options"
:v-model="userSettings[setting.id]"
:model-value="userSettings[setting.id]"
:selected="userSettings[setting.id]"
/>
<FormCheckRadio
v-if="setting.type == Boolean"
:v-model="userSettings[setting.id]"
:model-value="userSettings[setting.id]"
type="switch"
/>
</FormField>
</div>
<template #footer>
<div class="space-x-2">
<BaseButton type="submit" color="success" label="Save" />
<BaseButton type="submit" color="danger" label="Revert" />
</div>
</template>
</CardBox>
</div>
</SectionMain>
</LayoutAuthenticated>
</template>

View File

@@ -12,7 +12,7 @@ import FormControl from "@/components/FormControl.vue";
<template>
<LayoutAuthenticated>
<SectionMain>
<UserCard class="mb-6" use-small />
<UserCard class="mb-6" use-small even-smaller />
<SectionTitleLine
:icon="mdiAccountTieHat"
title="Profile Customizations"
@@ -21,7 +21,7 @@ import FormControl from "@/components/FormControl.vue";
<div>
<CardBox>
<div class="grid grid-cols-3 gap-6">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div>
<h2 class="text-lg mb-2">Avatar Source</h2>
<FormControl

View File

@@ -194,8 +194,8 @@ const setGoals = [
</p>
</div>
<template v-if="createGoal()" #footer>
<div class="space-x-2">
<template #footer>
<div v-if="formData.deadline !== '...'" class="space-x-2">
<BaseButton
type="submit"
color="success"

View File

@@ -17,7 +17,7 @@ import PillTag from "@/components/PillTag.vue";
<template>
<LayoutAuthenticated>
<SectionMain>
<UserCard class="mb-6" use-small />
<UserCard class="mb-6" use-small even-smaller />
<SectionTitleLine
:icon="mdiServerNetwork"
title="Server Integrations"

View File

@@ -45,7 +45,7 @@ const submitPass = () => {
<template>
<LayoutAuthenticated>
<SectionMain>
<UserCard class="mb-6" use-small />
<UserCard class="mb-6" use-small even-smaller />
<SectionTitleLine :icon="mdiAccount" title="Profile Settings" main />
<CardBox is-form class="mb-6" @submit.prevent="">