mirror of
https://github.com/PhaseII-eAmusement-Network/PhaseWeb3-Vue.git
synced 2026-04-24 06:48:56 -05:00
Add version system, add groundwork for rivals, add new update modal, clean up game constants
This commit is contained in:
parent
d3af72808b
commit
b92c78f48b
|
|
@ -1,3 +1,4 @@
|
|||
VITE_APP_VERSION="3.0.1"
|
||||
VITE_API_URL="http://10.5.7.5:8000/"
|
||||
VITE_API_KEY="your_api_key_should_be_here"
|
||||
VITE_ASSET_PATH="/assets"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
VITE_APP_VERSION="3.0.1"
|
||||
VITE_API_URL="https://restfulsleep.phaseii.network"
|
||||
VITE_API_KEY="your_api_key_should_be_here"
|
||||
VITE_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/web-assets"
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@
|
|||
<noscript>
|
||||
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<!-- Snow -->
|
||||
<div id="particles-js"></div>
|
||||
<script src="/assets/particles.js"></script>
|
||||
<!-- Particles -->
|
||||
<!-- <div id="particles-js"></div>
|
||||
<script src="/assets/particles.js"></script> -->
|
||||
<!-- <script src="/assets/network.js"></script> -->
|
||||
|
||||
<script src="/assets/network.js"></script>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
|
||||
|
|
|
|||
3395
package-lock.json
generated
3395
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
3
public/data-sources/changelog.json
Normal file
3
public/data-sources/changelog.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"3.0.1": ["- (Feature) Added update popup", "- (Optimization) Disabled ParticlesJS for the time being. This will be returned as an option in the future.", "- (Optimization) Fill in more score table data for GFDM.", "- (soon™️) I've started rival support, but it's not ready just yet. Stay tuned!"]
|
||||
}
|
||||
|
|
@ -55,6 +55,10 @@ const props = defineProps({
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
tooltip: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const is = computed(() => {
|
||||
|
|
@ -128,6 +132,12 @@ const componentClass = computed(() => {
|
|||
:target="target"
|
||||
:disabled="disabled"
|
||||
>
|
||||
<div
|
||||
v-if="tooltip"
|
||||
class="absolute bottom-full left-1/2 mb-1 -translate-x-1/2 whitespace-nowrap rounded bg-black px-2 py-1 text-xs text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200 z-10"
|
||||
>
|
||||
{{ tooltip }}
|
||||
</div>
|
||||
<BaseIcon v-if="icon" :path="icon" :size="iconSize" />
|
||||
<span v-if="label" :class="labelClass">{{ label }}</span>
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ import {
|
|||
mdiAccountDetails,
|
||||
mdiPlaylistMusicOutline,
|
||||
mdiFormatListText,
|
||||
mdiAxeBattle,
|
||||
} from "@mdi/js";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { dashCode } from "@/constants/userData";
|
||||
import { GameConstants, getGameInfo } from "@/constants";
|
||||
import { GameConstants, getGameInfo, getRivalInfo } from "@/constants";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import UserEmblem from "@/components/UserEmblem.vue";
|
||||
import UserQpro from "@/components/UserQpro.vue";
|
||||
|
|
@ -131,6 +132,14 @@ onMounted(async () => {
|
|||
color="info"
|
||||
label="Edit Profile"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!useSmall && game && getRivalInfo(game, version)"
|
||||
:icon="mdiAxeBattle"
|
||||
:href="`/#/games/${game}/rivals`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
label="Rivals"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="!useSmall && !thisGame.noScores"
|
||||
:href="`/#/games/${game}/scores/${profile.userId}`"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import CardBox from "@/components/CardBox.vue";
|
||||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import GameIcon from "@/components/GameIcon.vue";
|
||||
import BaseButton from "./BaseButton.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { getGameInfo } from "@/constants";
|
||||
|
||||
defineProps({
|
||||
|
|
@ -3,11 +3,11 @@ import { computed, ref } from "vue";
|
|||
import CardBox from "@/components/CardBox.vue";
|
||||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "./BaseIcon.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import { mdiEmailAlertOutline } from "@mdi/js";
|
||||
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
import { loadCookie, saveCookie, deleteCookie } from "@/stores/cookies";
|
||||
import { loadCookie, saveCookie } from "@/stores/cookies";
|
||||
|
||||
const mainStore = useMainStore();
|
||||
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
import { useRouter } from "vue-router";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import BaseIcon from "./BaseIcon.vue";
|
||||
import BaseButton from "./BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { mdiCheckOutline, mdiCloseOutline } from "@mdi/js";
|
||||
|
||||
const $router = useRouter();
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
<script setup>
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import BaseIcon from "./BaseIcon.vue";
|
||||
import BaseButton from "./BaseButton.vue";
|
||||
import { mdiCheckOutline, mdiCloseOutline } from "@mdi/js";
|
||||
|
||||
defineProps({
|
||||
active: {
|
||||
|
|
@ -4,7 +4,7 @@ import OverlayLayer from "@/components/OverlayLayer.vue";
|
|||
import GameIcon from "@/components/GameIcon.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormCheckRadio from "@/components/FormCheckRadio.vue";
|
||||
import BaseButton from "./BaseButton.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { getGameInfo } from "@/constants";
|
||||
import { APIGetProfile } from "@/stores/api/profile";
|
||||
import { onMounted, ref } from "vue";
|
||||
117
src/components/Modal/UpdateModal.vue
Normal file
117
src/components/Modal/UpdateModal.vue
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<script setup>
|
||||
import axios from "axios";
|
||||
import { ref, onMounted } from "vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import { mdiSourceBranchRefresh } from "@mdi/js";
|
||||
import { APIUserAppUpdate } from "@/stores/api/account";
|
||||
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
|
||||
const changelog = ref(null);
|
||||
const appVersion = import.meta.env.VITE_APP_VERSION;
|
||||
const activeState = ref(true);
|
||||
|
||||
async function loadChangelogs() {
|
||||
try {
|
||||
const response = await axios.get(`/data-sources/changelog.json`);
|
||||
if (response.data) {
|
||||
changelog.value = response.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading changelog:", error.message);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadChangelogs();
|
||||
});
|
||||
|
||||
function isActive() {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
if (mainStore.userData.webVersions) {
|
||||
if (mainStore.userData.webVersions.includes(appVersion)) {
|
||||
activeState.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mainStore.userData.disableUpdateModal) {
|
||||
activeState.value = false;
|
||||
}
|
||||
|
||||
return activeState.value;
|
||||
}
|
||||
|
||||
async function updateUserData(disable = false) {
|
||||
var data = null;
|
||||
|
||||
try {
|
||||
data = await APIUserAppUpdate(appVersion, disable);
|
||||
} catch (error) {
|
||||
console.error("Failed to update user:", error);
|
||||
}
|
||||
|
||||
if (data?.status === "success") {
|
||||
activeState.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="isActive()">
|
||||
<OverlayLayer v-if="activeState" :transparent="true">
|
||||
<CardBox
|
||||
class="shadow-lg max-h-modal w-11/12 md:w-3/5 lg:w-2/5 xl:w-4/12 z-50 text-white/90"
|
||||
>
|
||||
<div class="grid text-center justify-center grid-cols-1 gap-3">
|
||||
<div class="place-self-center">
|
||||
<BaseIcon
|
||||
:path="mdiSourceBranchRefresh"
|
||||
class="text-emerald-600"
|
||||
w="w-20"
|
||||
:size="45"
|
||||
/>
|
||||
<h1 class="text-2xl font-bold">Since you've been gone...</h1>
|
||||
<h1 class="text-lg md:text-xl">
|
||||
We've updated the site! These updates include feature updates and
|
||||
bugfixes.
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<hr class="border-t border-1 mt-3 w-full" />
|
||||
|
||||
<div
|
||||
v-if="changelog"
|
||||
class="text-lg md:text-xl space-y-2 text-left text-pink-500 bg-slate-950 p-2"
|
||||
>
|
||||
<h1>Changelog:</h1>
|
||||
<h2
|
||||
v-for="change of changelog[appVersion] ?? ['No changes!']"
|
||||
:key="change"
|
||||
class="font-mono"
|
||||
>
|
||||
{{ change }}
|
||||
</h2>
|
||||
</div>
|
||||
<h2 class="font-mono text-pink-500">Version: {{ appVersion }}</h2>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<BaseButton
|
||||
label="Close"
|
||||
color="success"
|
||||
@click="updateUserData(false)"
|
||||
/>
|
||||
<BaseButton
|
||||
label="Never Show Again"
|
||||
color="danger"
|
||||
@click="updateUserData(true)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
</OverlayLayer>
|
||||
</template>
|
||||
</template>
|
||||
|
|
@ -304,38 +304,47 @@ const GITADORA_VERSION_DATA = [
|
|||
{
|
||||
id: VersionConstants.GITADORA,
|
||||
label: "Original",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GITADORA_OVERDRIVE,
|
||||
label: "OverDrive",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GITADORA_TRIBOOST,
|
||||
label: "Tri-Boost",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GITADORA_TRIBOOST_RE_EVOLVE,
|
||||
label: "Tri-Boost RE:Evolve",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GITADORA_MATIXX,
|
||||
label: "Matixx",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GITADORA_EXCHAIN,
|
||||
label: "EXCHAIN",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GITADORA_NEXTAGE,
|
||||
label: "Nex+Age",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GITADORA_HIGH_VOLTAGE,
|
||||
label: "HIGH-VOLTAGE",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GITADORA_FUZZUP,
|
||||
label: "FUZZUP",
|
||||
maxRivals: 3,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -428,10 +437,7 @@ export const gameData = [
|
|||
icon: null,
|
||||
cardBG: null,
|
||||
noRivals: true,
|
||||
scoreHeaders: [
|
||||
{ text: "Combos", value: "data.combo" },
|
||||
{ text: "Halo", value: "halo" },
|
||||
],
|
||||
scoreHeaders: [{ text: "Combos", value: "data.combo" }],
|
||||
chartTable: {
|
||||
0: "1A",
|
||||
1: "2A",
|
||||
|
|
@ -566,34 +572,42 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.DDR_X2,
|
||||
label: "X2",
|
||||
maxRivals: 1,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_X3_VS_2ND_MIX,
|
||||
label: "X3 vs. 2ND MIX",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_2013,
|
||||
label: "(2013)",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_2014,
|
||||
label: "(2014)",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_ACE,
|
||||
label: "Ace",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_A20,
|
||||
label: "A20",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_A20_PLUS,
|
||||
label: "A20 PLUS",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_A3,
|
||||
label: "A3",
|
||||
maxRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -656,6 +670,7 @@ export const gameData = [
|
|||
icon: `${ASSET_PATH}/icon/ddr.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/ddr.webp`,
|
||||
assetId: "ddr",
|
||||
gameOptions: DDROptions,
|
||||
videoTable: [VersionConstants.DDR_A20_PLUS],
|
||||
scoreHeaders: [
|
||||
{ text: "Combos", value: "data.combo" },
|
||||
|
|
@ -774,6 +789,7 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.DDR_A20_PLUS,
|
||||
label: "OmniMIX (A20 PLUS)",
|
||||
maxRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -799,7 +815,7 @@ export const gameData = [
|
|||
],
|
||||
scoreHeaders: [
|
||||
{ text: "Combos", value: "data.combo" },
|
||||
{ text: "Medal", value: "medal", width: 140 },
|
||||
{ text: "Medal", value: "medal", width: 100 },
|
||||
{ text: "SKILL %", value: "data.skill_perc", width: 90 },
|
||||
{ text: "SKILL POINT", value: "data.skill_points", width: 140 },
|
||||
],
|
||||
|
|
@ -875,22 +891,27 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.DRUMMANIA_V4,
|
||||
label: "V4: ROCKxROCK",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DRUMMANIA_V5,
|
||||
label: "V5: ROCK TO INFINITY!",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DRUMMANIA_V6,
|
||||
label: "V6: BLAZING!!!!",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DRUMMANIA_V7,
|
||||
label: "V7",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DRUMMANIA_V8,
|
||||
label: "V8",
|
||||
maxRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -1040,7 +1061,7 @@ export const gameData = [
|
|||
gameOptions: GFDMOptions,
|
||||
scoreHeaders: [
|
||||
{ text: "Combos", value: "data.combo" },
|
||||
{ text: "Medal", value: "medal", width: 140 },
|
||||
{ text: "Medal", value: "medal", width: 100 },
|
||||
{ text: "SKILL %", value: "data.skill_perc", width: 90 },
|
||||
{ text: "SKILL POINT", value: "data.skill_points", width: 140 },
|
||||
],
|
||||
|
|
@ -1142,22 +1163,27 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.GUITARFREAKS_V4,
|
||||
label: "V4: ROCKxROCK",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GUITARFREAKS_V5,
|
||||
label: "V5: ROCK TO INFINITY!",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GUITARFREAKS_V6,
|
||||
label: "V6: BLAZING!!!!",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GUITARFREAKS_V7,
|
||||
label: "V7",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.GUITARFREAKS_V8,
|
||||
label: "V8",
|
||||
maxRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -1169,6 +1195,7 @@ export const gameData = [
|
|||
cardBG: `${ASSET_PATH}/card/iidx.webp`,
|
||||
assetId: "iidx",
|
||||
gameOptions: IIDXOptions,
|
||||
splitRivals: true,
|
||||
videoTable: [
|
||||
VersionConstants.IIDX_TRICORO,
|
||||
VersionConstants.IIDX_SPADA,
|
||||
|
|
@ -1315,50 +1342,62 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.IIDX_TRICORO,
|
||||
label: "tricoro",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_SPADA,
|
||||
label: "SPADA",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_PENDUAL,
|
||||
label: "PENDUAL",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_COPULA,
|
||||
label: "COPULA",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_SINOBUZ,
|
||||
label: "SINOBUZ",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_CANNON_BALLERS,
|
||||
label: "CANNON BALLERS",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_ROOTAGE,
|
||||
label: "ROOTAGE",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_HEROIC_VERSE,
|
||||
label: "HEROIC VERSE",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_BISTROVER,
|
||||
label: "BISTROVER",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_CASTHOUR,
|
||||
label: "CastHour",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_RESIDENT,
|
||||
label: "RESIDENT",
|
||||
maxRivals: 5,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.IIDX_EPOLIS,
|
||||
label: "EPOLIS",
|
||||
maxRivals: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -1537,30 +1576,37 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.JUBEAT_SAUCER,
|
||||
label: "Saucer",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.JUBEAT_SAUCER_FULFILL,
|
||||
label: "Saucer Fulfill",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.JUBEAT_PROP,
|
||||
label: "Prop",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.JUBEAT_QUBELL,
|
||||
label: "Qubell",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.JUBEAT_CLAN,
|
||||
label: "Clan",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.JUBEAT_FESTO,
|
||||
label: "Festo",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.JUBEAT_AVE,
|
||||
label: "Avenue",
|
||||
maxRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -1778,38 +1824,47 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.POPN_MUSIC_TUNE_STREET,
|
||||
label: "TUNE STREET",
|
||||
maxRivals: 2,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.POPN_MUSIC_FANTASIA,
|
||||
label: "fantasia",
|
||||
maxRivals: 2,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.POPN_MUSIC_SUNNY_PARK,
|
||||
label: "Sunny Park",
|
||||
maxRivals: 2,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.POPN_MUSIC_LAPISTORIA,
|
||||
label: "ラピストリア (Lapistoria)",
|
||||
maxRivals: 4,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.POPN_MUSIC_ECLALE,
|
||||
label: "éclale",
|
||||
maxRivals: 4,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.POPN_MUSIC_USANEKO,
|
||||
label: "うさぎと猫と少年の夢 (Usaneko)",
|
||||
maxRivals: 4,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.POPN_MUSIC_PEACE,
|
||||
label: "peace",
|
||||
maxRivals: 4,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.POPN_MUSIC_KAIMEI_RIDDLES,
|
||||
label: "解明リドルズ (Kaimei riddles)",
|
||||
maxRivals: 4,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.POPN_MUSIC_UNILAB,
|
||||
label: "UniLab",
|
||||
maxRivals: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -1843,22 +1898,27 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.REFLEC_BEAT_LIMELIGHT,
|
||||
label: "Limelight",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.REFLEC_BEAT_COLETTE,
|
||||
label: "Colette",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.REFLEC_BEAT_GROOVIN,
|
||||
label: "groovin'!!",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.REFLEC_BEAT_VOLZZA,
|
||||
label: "VOLZZA",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.REFLEC_BEAT_VOLZZA_2,
|
||||
label: "VOLZZA 2",
|
||||
maxRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -1893,26 +1953,32 @@ export const gameData = [
|
|||
{
|
||||
id: VersionConstants.SDVX_BOOTH,
|
||||
label: "BOOTH",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.SDVX_INFINITE_INFECTION,
|
||||
label: "-II- Infinite Infection",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.SDVX_GRAVITY_WARS,
|
||||
label: "GRAVITY WARS",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.SDVX_HEAVENLY_HAVEN,
|
||||
label: "HEAVENLY HAVEN",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.SDVX_VIVID_WAVE,
|
||||
label: "VIVID WAVE",
|
||||
maxRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.SDVX_EXCEED_GEAR,
|
||||
label: "EXCEED GEAR",
|
||||
maxRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -1983,7 +2049,7 @@ export function getGameTitle(game, version) {
|
|||
var output = gameObject.name;
|
||||
|
||||
const versions = gameObject.versions;
|
||||
if (versions !== null) {
|
||||
if (versions !== undefined) {
|
||||
const thisVersion = versions.find((x) => x.id == version);
|
||||
if (thisVersion !== undefined) {
|
||||
output += ` ${thisVersion.name}`;
|
||||
|
|
@ -1992,3 +2058,18 @@ export function getGameTitle(game, version) {
|
|||
|
||||
return output;
|
||||
}
|
||||
|
||||
export function getRivalInfo(game, version) {
|
||||
const gameObject = gameData.find((x) => x.id == game);
|
||||
var output = null;
|
||||
|
||||
const versions = gameObject.versions;
|
||||
if (versions !== undefined) {
|
||||
const thisVersion = versions.find((x) => x.id == version);
|
||||
if (thisVersion !== undefined) {
|
||||
output = thisVersion.maxRivals;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ import { useRouter, useRoute } from "vue-router";
|
|||
import menuNavBar from "@/menuNavBar.js";
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
import LoadingModal from "@/components/LoadingModal.vue";
|
||||
// import EmailModal from "@/components/EmailModal.vue";
|
||||
import LoadingModal from "@/components/Modal/LoadingModal.vue";
|
||||
// import EmailModal from "@/components/Modal/EmailModal.vue";
|
||||
import UpdateModal from "@/components/Modal/UpdateModal.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import NavBar from "@/components/NavBar.vue";
|
||||
import NavBarItemPlain from "@/components/NavBarItemPlain.vue";
|
||||
|
|
@ -238,6 +239,10 @@ const menuAside = computed(() => {
|
|||
'overflow-hidden lg:overflow-visible': isAsideMobileExpanded,
|
||||
}"
|
||||
>
|
||||
<template v-if="userLoaded">
|
||||
<UpdateModal class="transition-opacity duration-300 ease-out" />
|
||||
<!-- <EmailModal class="transition-opacity duration-300 ease-out" /> -->
|
||||
</template>
|
||||
<LoadingModal
|
||||
:active="loading || saving"
|
||||
:is-save="saving"
|
||||
|
|
@ -248,7 +253,6 @@ const menuAside = computed(() => {
|
|||
'opacity-0': !loading && !saving,
|
||||
}"
|
||||
/>
|
||||
<!-- <EmailModal class="transition-opacity duration-300 ease-out" /> -->
|
||||
<div
|
||||
v-if="userLoaded"
|
||||
:class="[layoutAsidePadding, { 'ml-60 lg:ml-0': isAsideMobileExpanded }]"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { useMainStore } from "@/stores/main.js";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
import { ref, watch } from "vue";
|
||||
import LoadingModal from "@/components/LoadingModal.vue";
|
||||
import LoadingModal from "@/components/Modal/LoadingModal.vue";
|
||||
const mainStore = useMainStore();
|
||||
|
||||
const loading = ref(mainStore.isLoading);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { useMainStore } from "@/stores/main";
|
||||
const mainStore = useMainStore();
|
||||
|
||||
export async function APIEmailAuth(email) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/auth/emailAuth`, "POST", {
|
||||
email: email,
|
||||
|
|
@ -14,6 +15,8 @@ export async function APIEmailAuth(email) {
|
|||
}
|
||||
|
||||
export async function APICheckKey(key) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/auth/check2FAKey`, "POST", {
|
||||
key: key,
|
||||
|
|
@ -26,6 +29,8 @@ export async function APICheckKey(key) {
|
|||
}
|
||||
|
||||
export async function APIResetPassword(key, newPassword, confirmPassword) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/auth/changePassword`, "POST", {
|
||||
key: key,
|
||||
|
|
@ -44,6 +49,8 @@ export async function APIUpdatePassword(
|
|||
newPassword,
|
||||
confirmPassword
|
||||
) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/updatePassword`, "POST", {
|
||||
currentPassword: currentPassword,
|
||||
|
|
@ -58,6 +65,8 @@ export async function APIUpdatePassword(
|
|||
}
|
||||
|
||||
export async function APIRegisterUser(newProfile) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user`, "PUT", newProfile);
|
||||
return data;
|
||||
|
|
@ -68,6 +77,8 @@ export async function APIRegisterUser(newProfile) {
|
|||
}
|
||||
|
||||
export async function APIGetCards() {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/card`);
|
||||
return data.cards;
|
||||
|
|
@ -78,6 +89,8 @@ export async function APIGetCards() {
|
|||
}
|
||||
|
||||
export async function APIPutCard(cardId) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/card`, "POST", {
|
||||
cardId: cardId,
|
||||
|
|
@ -90,6 +103,8 @@ export async function APIPutCard(cardId) {
|
|||
}
|
||||
|
||||
export async function APIDeleteCard(cardId) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const confirmed = window.confirm("Are you really?");
|
||||
if (confirmed) {
|
||||
|
|
@ -105,6 +120,8 @@ export async function APIDeleteCard(cardId) {
|
|||
}
|
||||
|
||||
export async function APIStartTakeover(cardId, pin) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(
|
||||
`/user/takeover?cardId=${cardId}&pin=${pin}`
|
||||
|
|
@ -120,6 +137,8 @@ export async function APIStartTakeover(cardId, pin) {
|
|||
}
|
||||
|
||||
export async function APISaveTakeover(cardId, pin, mergeSettings) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/takeover`, "POST", {
|
||||
cardId: cardId,
|
||||
|
|
@ -134,6 +153,8 @@ export async function APISaveTakeover(cardId, pin, mergeSettings) {
|
|||
}
|
||||
|
||||
export async function APIGetPlayVideos() {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/playVideos`);
|
||||
return data.data;
|
||||
|
|
@ -144,6 +165,8 @@ export async function APIGetPlayVideos() {
|
|||
}
|
||||
|
||||
export async function APIGetUserContent(type) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/content?type=${type}`);
|
||||
return data.data;
|
||||
|
|
@ -154,6 +177,8 @@ export async function APIGetUserContent(type) {
|
|||
}
|
||||
|
||||
export async function APIRemoveIntegration(service) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const confirmed = window.confirm("Are you really?");
|
||||
if (confirmed) {
|
||||
|
|
@ -170,6 +195,8 @@ export async function APIRemoveIntegration(service) {
|
|||
}
|
||||
|
||||
export async function APIIntegrateWith(service, code) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/integrate/${service}`, "POST", {
|
||||
code: code,
|
||||
|
|
@ -182,6 +209,8 @@ export async function APIIntegrateWith(service, code) {
|
|||
}
|
||||
|
||||
export async function APIUserCustomize(customize) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/customize`, "POST", {
|
||||
customize: customize,
|
||||
|
|
@ -192,3 +221,18 @@ export async function APIUserCustomize(customize) {
|
|||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function APIUserAppUpdate(version = null, disable = false) {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/appVersion`, "POST", {
|
||||
version: version,
|
||||
disable: disable,
|
||||
});
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log(`Error saving user!`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import { useMainStore } from "@/stores/main";
|
||||
const mainStore = useMainStore();
|
||||
|
||||
export async function APIGetAllProfiles(game) {
|
||||
export async function APIGetAllProfiles(game, version = null) {
|
||||
try {
|
||||
const data = await mainStore.callApi(`/game/${game}/profiles`);
|
||||
const data = await mainStore.callApi(
|
||||
`/game/${game}/profiles?version=${version}`
|
||||
);
|
||||
return data.data;
|
||||
} catch (error) {
|
||||
console.log("Error fetching profiles:", error);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import { loadUserAuthKey, saveUserAuthKey } from "@/stores/auth";
|
|||
|
||||
export const useMainStore = defineStore("main", {
|
||||
state: () => ({
|
||||
/* App Information */
|
||||
appVersion: import.meta.env.VITE_APP_VERSION,
|
||||
|
||||
/* User */
|
||||
userId: null,
|
||||
userName: null,
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@ headers.push(
|
|||
{ text: "Last Play", value: "stats.last_play_timestamp", width: 150 },
|
||||
{ text: "Last Arcade", value: "stats.last_play_arcade", width: 150 },
|
||||
{ text: "Plays", value: "stats.total_plays", sortable: true, width: 50 }
|
||||
// { text: "Last Arcade", value: "last.arcade", sortable: true, width: 150 }
|
||||
);
|
||||
|
||||
if (thisGame.playerHeaders) {
|
||||
|
|
|
|||
|
|
@ -155,6 +155,16 @@ function formatScores(scores) {
|
|||
item.data.music_rate = item.data?.music_rate / 10;
|
||||
}
|
||||
|
||||
if (item.data?.excellent) {
|
||||
item.medal = "EX FC";
|
||||
} else if (item.data?.fullcombo) {
|
||||
item.medal = "FC";
|
||||
} else if (item.data?.clear) {
|
||||
item.medal = "CLEARED";
|
||||
} else {
|
||||
item.medal = "FAILED";
|
||||
}
|
||||
|
||||
formattedItems.push(item);
|
||||
}
|
||||
return formattedItems;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { reactive } from "vue";
|
||||
import { reactive, watch, ref, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { mdiSwordCross, mdiPlus } from "@mdi/js";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
|
|
@ -8,61 +8,83 @@ 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 FormControl from "@/components/FormControl.vue";
|
||||
|
||||
import { APIGetProfile, APIGetAllProfiles } from "@/stores/api/profile";
|
||||
import { getGameInfo } from "@/constants";
|
||||
const ASSET_PATH = import.meta.env.VITE_ASSET_PATH;
|
||||
import { getVideoSource, getCardStyle } from "@/constants/sources";
|
||||
import { dashCode } from "@/constants/userData";
|
||||
|
||||
const $route = useRoute();
|
||||
const $router = useRouter();
|
||||
var gameID = null;
|
||||
var thisGame = null;
|
||||
|
||||
const profile = {
|
||||
id: 1,
|
||||
name: "Trmazi",
|
||||
extid: 12345678,
|
||||
avatar:
|
||||
"https://static.wikia.nocookie.net/dancedancerevolutionddr/images/3/3b/Yuni_img1.gif/",
|
||||
last: {
|
||||
arcade: "GhettoCade",
|
||||
date: "7/16/2023",
|
||||
},
|
||||
};
|
||||
|
||||
const rivals = [
|
||||
{
|
||||
id: 1,
|
||||
name: "TRMAZI",
|
||||
rivalID: "1234-5678",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "BLADE",
|
||||
rivalID: "1454-5687",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "HO!",
|
||||
rivalID: "5364-5568",
|
||||
},
|
||||
];
|
||||
gameID = $route.params.game;
|
||||
thisGame = getGameInfo(gameID);
|
||||
|
||||
const profile = ref(null);
|
||||
const allProfiles = ref([]);
|
||||
const versionForm = reactive({
|
||||
currentVersion: null,
|
||||
});
|
||||
|
||||
const filterForm = reactive({
|
||||
filter: null,
|
||||
});
|
||||
watch(
|
||||
() => versionForm.currentVersion,
|
||||
() => {
|
||||
loadProfile();
|
||||
loadAllProfiles();
|
||||
}
|
||||
);
|
||||
|
||||
gameID = $route.params.game;
|
||||
thisGame = getGameInfo(gameID);
|
||||
onMounted(async () => {
|
||||
loadAllProfiles();
|
||||
loadProfile();
|
||||
});
|
||||
|
||||
if (!thisGame.versions) {
|
||||
versionForm.currentVersion = 1;
|
||||
}
|
||||
|
||||
async function loadProfile() {
|
||||
try {
|
||||
profile.value = null;
|
||||
const data = await APIGetProfile(gameID, versionForm.currentVersion);
|
||||
profile.value = data;
|
||||
|
||||
if (data && !versionForm.currentVersion) {
|
||||
versionForm.currentVersion = data.versions[data.versions.length - 1];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch user profile data:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadAllProfiles() {
|
||||
try {
|
||||
const data = await APIGetAllProfiles(gameID, versionForm.currentVersion);
|
||||
allProfiles.value = data;
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch profile data:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function filterVersions(haveVersions) {
|
||||
var filtered = [];
|
||||
for (const version of thisGame.versions) {
|
||||
if (haveVersions.includes(version.id)) {
|
||||
filtered.push(version);
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
const filterForm = reactive({
|
||||
filter: null,
|
||||
});
|
||||
|
||||
if (!thisGame) {
|
||||
$router.push({
|
||||
name: "ErrorPage",
|
||||
|
|
@ -72,60 +94,67 @@ if (!thisGame) {
|
|||
});
|
||||
}
|
||||
|
||||
function filterUsers() {
|
||||
function filterProfiles() {
|
||||
if (filterForm.filter) {
|
||||
return rivals.filter(
|
||||
return allProfiles.value.filter(
|
||||
(rival) =>
|
||||
rival.name.toLowerCase().includes(filterForm.filter.toLowerCase()) ||
|
||||
rival.rivalID.toLowerCase().includes(filterForm.filter.toLowerCase())
|
||||
rival.username
|
||||
.toLowerCase()
|
||||
.includes(filterForm.filter.toLowerCase()) ||
|
||||
rival.extid
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.includes(filterForm.filter.toLowerCase())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getSources() {
|
||||
var sources = null;
|
||||
if (!versionForm.currentVersion) {
|
||||
sources = thisGame.cardBG;
|
||||
} else {
|
||||
sources = `${ASSET_PATH}/games/${thisGame.id}/card/${versionForm.currentVersion}.webp`;
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
function getCardStyle() {
|
||||
return `
|
||||
background-image: url('${getSources()}');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<div class="md:flex md:justify-end pb-6 items-center">
|
||||
<div
|
||||
v-if="thisGame.versions"
|
||||
class="mt-2 md:mt-0 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
|
||||
v-if="versionForm.currentVersion"
|
||||
:style="getCardStyle()"
|
||||
class="rounded-2xl mb-6"
|
||||
:style="getCardStyle(thisGame, versionForm.currentVersion)"
|
||||
class="rounded-2xl mb-6 card-container"
|
||||
>
|
||||
<div class="bg-white dark:bg-slate-900/90 rounded-2xl pt-6 p-3">
|
||||
<video
|
||||
autoplay
|
||||
muted
|
||||
loop
|
||||
playsinline
|
||||
:src="getVideoSource(thisGame, versionForm.currentVersion)"
|
||||
class="background-video"
|
||||
></video>
|
||||
<div
|
||||
class="bg-white dark:bg-slate-900/90 rounded-2xl pt-6 p-3 card-content"
|
||||
>
|
||||
<div class="w-full">
|
||||
<ProfileCard use-small :profile="profile" />
|
||||
<div
|
||||
class="md:flex md:px-5 md:space-x-10 md:justify-between md:items-center"
|
||||
>
|
||||
<GameTitleLine :path="thisGame.icon" :title="thisGame.name" />
|
||||
<div
|
||||
v-if="thisGame.versions && profile"
|
||||
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="filterVersions(profile.versions)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="profile" class="w-full">
|
||||
<ProfileCard
|
||||
:game="gameID"
|
||||
:version="versionForm.currentVersion"
|
||||
:profile="profile"
|
||||
use-small
|
||||
>
|
||||
</ProfileCard>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -144,35 +173,39 @@ function getCardStyle() {
|
|||
/>
|
||||
</FormField>
|
||||
|
||||
<div class="grid gap-3">
|
||||
<CardBox v-for="rival of filterUsers()" :key="rival.id">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex">
|
||||
<img
|
||||
class="w-10 mr-3"
|
||||
src="https://static.wikia.nocookie.net/dancedancerevolutionddr/images/3/3b/Yuni_img1.gif/"
|
||||
/>
|
||||
<div class="grid">
|
||||
<h1 class="text-lg">{{ rival.name }}</h1>
|
||||
<h2 class="text-md font-mono">{{ rival.rivalID }}</h2>
|
||||
</div>
|
||||
<div class="grid gap-4">
|
||||
<div
|
||||
v-for="player of filterProfiles()"
|
||||
:key="player.id"
|
||||
class="bg-slate-800 p-4 rounded-xl"
|
||||
>
|
||||
<div class="flex w-full place-content-between">
|
||||
<div>
|
||||
<h1 class="text-lg md:text-xl">{{ player.username }}</h1>
|
||||
<h2 class="text-md md:text-lg font-mono">
|
||||
{{ dashCode(player.extid) }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="flex align-middle">
|
||||
<BaseButton
|
||||
label="Add Rival"
|
||||
color="success"
|
||||
:disabled="player.userId == profile?.userId"
|
||||
tooltip="penis"
|
||||
/>
|
||||
</div>
|
||||
<BaseButton label="Add Rival" color="success" />
|
||||
</div>
|
||||
</CardBox>
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
|
||||
<SectionTitleLine :icon="mdiSwordCross" title="Rivals" main />
|
||||
<CardBox v-if="versionForm.currentVersion" class="mb-6">
|
||||
<div class="grid gap-3">
|
||||
<CardBox v-for="rival of rivals" :key="rival.id">
|
||||
<CardBox v-for="rival of profile?.rivals" :key="rival.id">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex">
|
||||
<img
|
||||
class="w-10 mr-3"
|
||||
src="https://static.wikia.nocookie.net/dancedancerevolutionddr/images/3/3b/Yuni_img1.gif/"
|
||||
/>
|
||||
<div class="grid">
|
||||
<h1 class="text-lg">{{ rival.name }}</h1>
|
||||
<h2 class="text-md font-mono">{{ rival.rivalID }}</h2>
|
||||
|
|
@ -181,6 +214,9 @@ function getCardStyle() {
|
|||
<BaseButton label="Remove Rival" color="danger" />
|
||||
</div>
|
||||
</CardBox>
|
||||
<CardBox v-if="!profile?.rivals">
|
||||
<h1 class="text-2xl">You have no rivals!</h1>
|
||||
</CardBox>
|
||||
</div>
|
||||
</CardBox>
|
||||
</SectionMain>
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import FormControl from "@/components/FormControl.vue";
|
|||
import FormCheckRadio from "@/components/FormCheckRadio.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
import MergeModal from "@/components/MergeModal.vue";
|
||||
import ConfirmMergeModal from "@/components/ConfirmMergeModal.vue";
|
||||
import MergeModal from "@/components/Modal/MergeModal.vue";
|
||||
import ConfirmMergeModal from "@/components/Modal/ConfirmMergeModal.vue";
|
||||
|
||||
import { APIStartTakeover, APISaveTakeover } from "@/stores/api/account";
|
||||
import { getGameInfo } from "@/constants";
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user