mirror of
https://github.com/PhaseII-eAmusement-Network/PhaseWeb3-Vue.git
synced 2026-07-20 18:09:42 -05:00
This commit is contained in:
parent
6552ed5208
commit
a200f27a17
|
|
@ -1,6 +1,8 @@
|
|||
<script setup>
|
||||
import { computed } from "vue";
|
||||
|
||||
const ASSET_PATH = import.meta.env.VITE_ASSET_PATH;
|
||||
|
||||
const props = defineProps({
|
||||
username: {
|
||||
type: String,
|
||||
|
|
@ -10,6 +12,10 @@ const props = defineProps({
|
|||
type: String,
|
||||
default: null,
|
||||
},
|
||||
border: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const avatar = computed(
|
||||
|
|
@ -29,12 +35,13 @@ const username = computed(() => props.username);
|
|||
height="200"
|
||||
class="w-full h-auto bg-gray-100 dark:bg-slate-800 rounded-full overflow-hidden drop-shadow-lg"
|
||||
/>
|
||||
<!-- <img
|
||||
:src="`${ASSET_PATH}/border/pride.webp`"
|
||||
<img
|
||||
v-if="border"
|
||||
:src="`${ASSET_PATH}/border/${border}.webp`"
|
||||
alt="border"
|
||||
class="absolute inset-0 w-full h-full overflow-hidden scale-[1.02]"
|
||||
style="object-fit: fill"
|
||||
/> -->
|
||||
/>
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@ const mainStore = useMainStore();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<UserAvatar :username="mainStore.userName" :avatar="mainStore.userAvatar">
|
||||
<UserAvatar
|
||||
:username="mainStore.userName"
|
||||
:avatar="mainStore.userAvatar"
|
||||
:border="mainStore.userCustomize?.border ?? null"
|
||||
>
|
||||
<slot />
|
||||
</UserAvatar>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -33,25 +33,19 @@ const mainStore = useMainStore();
|
|||
|
||||
const greeting = GetRandomMessage();
|
||||
|
||||
// var last = {
|
||||
// game: "beatmaniaIIDX",
|
||||
// version: "22 PENDUAL",
|
||||
// arcade: "Ho-House",
|
||||
// };
|
||||
|
||||
function getCardStyle(game) {
|
||||
if (game !== null) {
|
||||
return `
|
||||
background-image: url('${ASSET_PATH}/card/${game}.webp');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
`;
|
||||
}
|
||||
function getCardStyle() {
|
||||
return `
|
||||
background-image: url('${ASSET_PATH}/card/${
|
||||
mainStore.userCustomize?.card ?? "time"
|
||||
}.webp');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CardBox :style="getCardStyle(mainStore.userCardStyle)">
|
||||
<CardBox :style="getCardStyle()">
|
||||
<BaseLevel
|
||||
type="justify-around lg:justify-center md:space-x-4 lg:space-x-0"
|
||||
class="bg-white dark:bg-slate-900/90 rounded-2xl p-3"
|
||||
|
|
@ -59,17 +53,19 @@ function getCardStyle(game) {
|
|||
<UserAvatarCurrentUser class="w-28 md:w-32 lg:w-44 lg:mx-12" />
|
||||
<div class="space-y-3 text-center md:text-left lg:mx-12">
|
||||
<div class="space-y-2 md:space-y-0">
|
||||
<h1 v-if="!useSmall" class="text-2xl md:text-xl lg:text-2xl">
|
||||
<h1
|
||||
v-if="!useSmall && !mainStore.userCustomize.disableGreeting"
|
||||
class="text-2xl md:text-xl lg:text-2xl"
|
||||
>
|
||||
{{ greeting.header[0] }}<b>{{ mainStore.userName }} </b
|
||||
>{{ greeting.header[1] }}
|
||||
</h1>
|
||||
<h1 v-if="useSmall" class="text-3xl md:text-4xl">
|
||||
<h1
|
||||
v-if="useSmall || mainStore.userCustomize.disableGreeting"
|
||||
class="text-3xl md:text-4xl"
|
||||
>
|
||||
<b>{{ mainStore.userName }}</b>
|
||||
</h1>
|
||||
<p v-if="useSmall && !evenSmaller" class="text-md md:text-lg">
|
||||
<!-- Last seen playing <b>{{ last.game }} {{ last.version }}</b> at
|
||||
<b>{{ last.arcade }}</b> -->
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
v-if="!evenSmaller"
|
||||
|
|
@ -92,7 +88,10 @@ function getCardStyle(game) {
|
|||
/> -->
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!useSmall" class="text-center md:text-right">
|
||||
<div
|
||||
v-if="!useSmall && !mainStore.userCustomize.disableGreeting"
|
||||
class="text-center md:text-right"
|
||||
>
|
||||
<p class="text-xl md:text-lg lg:text-2lg">{{ greeting.comment }}</p>
|
||||
<p class="text-xs italic">Greeting by: {{ greeting.author }}</p>
|
||||
</div>
|
||||
|
|
|
|||
33
src/constants/customizations.js
Normal file
33
src/constants/customizations.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { gameData } from "@/constants";
|
||||
|
||||
export class ProfileCustomizations {
|
||||
static baseCardList = [
|
||||
{ id: "time", label: "Default" },
|
||||
{ id: "carpet", label: "Arcade Carpet" },
|
||||
{ id: "gradient", label: "Pink/Purple Gradient" },
|
||||
{ id: "pride", label: "Pride Flag" },
|
||||
{ id: "trans", label: "Trans Flag" },
|
||||
{ id: "loveplus", label: "LovePlus" },
|
||||
];
|
||||
|
||||
static get cardList() {
|
||||
const gameCards = gameData
|
||||
.filter((game) => !game.skip)
|
||||
.map((game) => ({
|
||||
id: game.assetId ? game.assetId : game.id,
|
||||
label: game.name,
|
||||
}));
|
||||
|
||||
return [...this.baseCardList, ...gameCards];
|
||||
}
|
||||
|
||||
static borderList = [
|
||||
{ id: "", label: "None" },
|
||||
{ id: "test", label: "Basic" },
|
||||
{ id: "swirl", label: "Swirl" },
|
||||
{ id: "pride", label: "Pride Flag" },
|
||||
{ id: "trans", label: "Trans Flag" },
|
||||
{ id: "nonbinary", label: "Non-Binary Flag" },
|
||||
{ id: "leaves", label: "Leaves" },
|
||||
];
|
||||
}
|
||||
|
|
@ -602,6 +602,7 @@ export const gameData = [
|
|||
name: "Classic DDR",
|
||||
icon: `${ASSET_PATH}/icon/ddr.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/ddr.webp`,
|
||||
assetId: "ddr",
|
||||
noRivals: true,
|
||||
noScores: true,
|
||||
noRecords: true,
|
||||
|
|
@ -654,6 +655,7 @@ export const gameData = [
|
|||
name: "DDR OmniMIX",
|
||||
icon: `${ASSET_PATH}/icon/ddr.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/ddr.webp`,
|
||||
assetId: "ddr",
|
||||
videoTable: [VersionConstants.DDR_A20_PLUS],
|
||||
scoreHeaders: [
|
||||
{ text: "Combos", value: "data.combo" },
|
||||
|
|
@ -1165,6 +1167,7 @@ export const gameData = [
|
|||
shortName: "IIDX",
|
||||
icon: `${ASSET_PATH}/icon/iidx.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/iidx.webp`,
|
||||
assetId: "iidx",
|
||||
gameOptions: IIDXOptions,
|
||||
videoTable: [
|
||||
VersionConstants.IIDX_TRICORO,
|
||||
|
|
@ -1364,6 +1367,7 @@ export const gameData = [
|
|||
name: "Classic IIDX",
|
||||
icon: `${ASSET_PATH}/icon/iidx.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/iidx.webp`,
|
||||
assetId: "iidx",
|
||||
noRivals: true,
|
||||
noScores: true,
|
||||
noRecords: true,
|
||||
|
|
@ -1678,6 +1682,7 @@ export const gameData = [
|
|||
name: "Hello! Pop'n Music",
|
||||
icon: `${ASSET_PATH}/icon/popn.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/popn.webp`,
|
||||
assetId: "popn",
|
||||
skip: true,
|
||||
noRivals: true,
|
||||
noScores: true,
|
||||
|
|
@ -1689,6 +1694,7 @@ export const gameData = [
|
|||
shortName: "pop'n",
|
||||
icon: `${ASSET_PATH}/icon/popn.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/popn.webp`,
|
||||
assetId: "popn",
|
||||
useUnicode: true,
|
||||
maxLength: 6,
|
||||
gameOptions: PopnMusicOptions,
|
||||
|
|
@ -1861,6 +1867,7 @@ export const gameData = [
|
|||
name: "Road Fighters 3D",
|
||||
icon: `${ASSET_PATH}/icon/rf.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/rf.webp`,
|
||||
assetId: "rf",
|
||||
skip: true,
|
||||
noRivals: true,
|
||||
noScores: true,
|
||||
|
|
@ -1923,6 +1930,7 @@ export const gameData = [
|
|||
name: "World Soccer",
|
||||
icon: `${ASSET_PATH}/icon/we.webp`,
|
||||
cardBG: `${ASSET_PATH}/card/we.webp`,
|
||||
assetId: "we",
|
||||
skip: false,
|
||||
noRivals: true,
|
||||
noScores: true,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
mdiAccount,
|
||||
mdiLogout,
|
||||
mdiBrushVariant,
|
||||
mdiServerNetwork,
|
||||
mdiCardAccountDetailsOutline,
|
||||
mdiAccountArrowLeftOutline,
|
||||
|
|
@ -15,6 +16,11 @@ export default [
|
|||
label: "Settings",
|
||||
to: "/profile",
|
||||
},
|
||||
{
|
||||
icon: mdiBrushVariant,
|
||||
label: "Customize",
|
||||
to: "/profile/customize",
|
||||
},
|
||||
{
|
||||
icon: mdiServerNetwork,
|
||||
label: "Integrations",
|
||||
|
|
|
|||
|
|
@ -50,14 +50,14 @@ const routes = [
|
|||
name: "profile",
|
||||
component: () => import("@/views/Profile/ProfileView.vue"),
|
||||
},
|
||||
// {
|
||||
// meta: {
|
||||
// title: "Customizations",
|
||||
// },
|
||||
// path: "/profile/customize",
|
||||
// name: "profile_customizations",
|
||||
// component: () => import("@/views/Profile/CustomizeView.vue"),
|
||||
// },
|
||||
{
|
||||
meta: {
|
||||
title: "Customizations",
|
||||
},
|
||||
path: "/profile/customize",
|
||||
name: "profile_customizations",
|
||||
component: () => import("@/views/Profile/CustomizeView.vue"),
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
title: "Integrations",
|
||||
|
|
|
|||
|
|
@ -180,3 +180,15 @@ export async function APIIntegrateWith(service, code) {
|
|||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function APIUserCustomize(customize) {
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/customize`, "POST", {
|
||||
customize: customize,
|
||||
});
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log(`Error saving user customize!`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ export const useMainStore = defineStore("main", {
|
|||
userProfiles: [],
|
||||
userArcades: [],
|
||||
profiles: {},
|
||||
userCustomize: {},
|
||||
|
||||
/* Field focus with ctrl+k (to register only once) */
|
||||
isFieldFocusRegistered: false,
|
||||
|
|
@ -65,6 +66,9 @@ export const useMainStore = defineStore("main", {
|
|||
if (payload.arcades) {
|
||||
this.userArcades = payload.arcades;
|
||||
}
|
||||
if (payload.customize) {
|
||||
this.userCustomize = payload.customize;
|
||||
}
|
||||
},
|
||||
|
||||
fetch(sampleDataKey) {
|
||||
|
|
@ -250,6 +254,7 @@ export const useMainStore = defineStore("main", {
|
|||
cardStyle: "time",
|
||||
profiles: user.profiles,
|
||||
arcades: user.arcades,
|
||||
customize: user.data?.customize,
|
||||
});
|
||||
this.userLoaded = true;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,69 @@
|
|||
<script setup>
|
||||
import { useMainStore } from "@/stores/main";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ref, watch } from "vue";
|
||||
import { mdiAccountTieHat } from "@mdi/js";
|
||||
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import UserCard from "@/components/UserCard.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import FormCheckRadio from "@/components/FormCheckRadio.vue";
|
||||
import { ProfileCustomizations } from "@/constants/customizations";
|
||||
import { APIUserCustomize } from "@/stores/api/account";
|
||||
|
||||
const $router = useRouter();
|
||||
const mainStore = useMainStore();
|
||||
const userCustomize = ref(mainStore.userCustomize);
|
||||
var originalData = JSON.parse(JSON.stringify(mainStore.userCustomize));
|
||||
|
||||
watch(
|
||||
() => mainStore.userCustomize,
|
||||
(newValue) => {
|
||||
userCustomize.value = newValue;
|
||||
originalData = JSON.parse(JSON.stringify(newValue));
|
||||
}
|
||||
);
|
||||
|
||||
async function updateCustomize() {
|
||||
var data = null;
|
||||
|
||||
try {
|
||||
data = await APIUserCustomize(userCustomize.value);
|
||||
} catch (error) {
|
||||
console.error("Failed to update customize:", error);
|
||||
}
|
||||
|
||||
if (data?.status === "success") {
|
||||
mainStore.userLoaded = false;
|
||||
$router.go();
|
||||
}
|
||||
}
|
||||
|
||||
function userChanged() {
|
||||
console.log(originalData);
|
||||
console.log(userCustomize.value);
|
||||
if (JSON.stringify(originalData) !== JSON.stringify(userCustomize.value)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function revert() {
|
||||
mainStore.userLoaded = false;
|
||||
$router.go();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<UserCard class="mb-6" use-small even-smaller />
|
||||
<UserCard class="mb-6" />
|
||||
<SectionTitleLine
|
||||
:icon="mdiAccountTieHat"
|
||||
title="Profile Customizations"
|
||||
|
|
@ -21,39 +72,44 @@ import FormControl from "@/components/FormControl.vue";
|
|||
|
||||
<div>
|
||||
<CardBox>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div>
|
||||
<h2 class="text-lg mb-2">Avatar Source</h2>
|
||||
<form @submit.prevent="updateCustomize">
|
||||
<FormField label="Profile Background">
|
||||
<FormControl
|
||||
:options="['Discord', 'Gravatar', 'Kamaitachi']"
|
||||
model-value="Gravatar"
|
||||
name="border"
|
||||
v-model="userCustomize.card"
|
||||
:options="ProfileCustomizations.cardList"
|
||||
:model-value="userCustomize.card ?? 'time'"
|
||||
name="card"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-lg mb-2">Avatar Border</h2>
|
||||
<FormControl
|
||||
:options="['Trans Flag', 'Pride Flag']"
|
||||
model-value="Trans Flag"
|
||||
name="border"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-lg mb-2">Profile Background</h2>
|
||||
<FormControl
|
||||
:options="['Trans Flag', 'Pride Flag']"
|
||||
model-value="Trans Flag"
|
||||
name="border"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</FormField>
|
||||
|
||||
<FormField label="Profile Border">
|
||||
<FormControl
|
||||
v-model="userCustomize.border"
|
||||
:options="ProfileCustomizations.borderList"
|
||||
:model-value="userCustomize.border ?? ''"
|
||||
name="border"
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField label="Disable Greeting">
|
||||
<FormCheckRadio
|
||||
v-model="userCustomize.disableGreeting"
|
||||
type="switch"
|
||||
:input-value="userCustomize.disableGreeting ?? false"
|
||||
name="disableGreeting"
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<template #footer>
|
||||
<div class="space-x-2">
|
||||
<BaseButton type="submit" color="success" label="Save" />
|
||||
<BaseButton type="submit" color="danger" label="Revert" />
|
||||
<BaseButton
|
||||
v-if="userChanged()"
|
||||
color="danger"
|
||||
label="Revert"
|
||||
@click="revert"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</form>
|
||||
</CardBox>
|
||||
</div>
|
||||
</SectionMain>
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ async function submitProfile() {
|
|||
const response = await mainStore.putUser(profileForm);
|
||||
if (response.status == "success") {
|
||||
profileLoading.value = false;
|
||||
mainStore.userLoaded = false;
|
||||
await mainStore.loadUser();
|
||||
$router.go();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user