diff --git a/src/components/OverlayLayer.vue b/src/components/OverlayLayer.vue
index 43f082a..e1b33ec 100644
--- a/src/components/OverlayLayer.vue
+++ b/src/components/OverlayLayer.vue
@@ -14,6 +14,10 @@ defineProps({
type: Boolean,
default: false,
},
+ active: {
+ type: Boolean,
+ default: true,
+ },
});
const emit = defineEmits(["overlay-click"]);
@@ -26,33 +30,20 @@ const styleStore = useStyleStore();
-
+
diff --git a/src/constants/developer/index.js b/src/constants/developer/index.js
new file mode 100644
index 0000000..ee6c05c
--- /dev/null
+++ b/src/constants/developer/index.js
@@ -0,0 +1,80 @@
+export const applicationIntents = [
+ {
+ id: "network",
+ label: "Read Network",
+ tip: "View network news, public profiles, and public arcades",
+ },
+ {
+ id: "read_user",
+ label: "Read User",
+ tip: "Allows this app to read a user that has authenticated through it",
+ },
+ {
+ id: "update_user",
+ label: "Update User",
+ tip: "Allows this app to update a user that has authenticated through it",
+ },
+ {
+ id: "read_profiles",
+ label: "Read Profiles",
+ tip: "Allows this app to read the game profiles of a user that has authenticated through it",
+ },
+ {
+ id: "update_profiles",
+ label: "Update Profiles",
+ tip: "Allows this app to update the game profiles of a user that has authenticated through it",
+ },
+ {
+ id: "read_scores",
+ label: "Read Scores",
+ tip: "Allows this app to read the scores and records of a user that has authenticated through it",
+ },
+ {
+ id: "read_arcade",
+ label: "Read Arcades",
+ tip: "Allows this app to read the arcades of a user that has authenticated through it",
+ },
+ {
+ id: "update_arcade",
+ label: "Update Arcades",
+ tip: "Allows this app to update an arcade of a user that has authenticated through it",
+ },
+ {
+ id: "webhook",
+ label: "Webhooks",
+ tip: "Allows this app to add and remove webhooks for a user that has authenticated through it",
+ },
+];
+
+export const applicationWebhooks = [
+ {
+ id: "network.news",
+ type: "network",
+ short: "news",
+ label: "Network News",
+ tip: "Called when a new news post is uploaded",
+ },
+ {
+ id: "network.maintenance",
+ type: "network",
+ short: "maintenance",
+ label: "Network Maintenance",
+ tip: "Called when a maintenance window is posted",
+ },
+ {
+ id: "arcade.event",
+ type: "arcade",
+ short: "event",
+ label: "Arcade PCB Events",
+ tip: "Called when a PCB event is sent. Requires an arcade to be specified",
+ fields: ["arcadeId"],
+ },
+ {
+ id: "arcade.paseli",
+ type: "arcade",
+ short: "paseli",
+ label: "Arcade PASELI",
+ tip: "Called when a PASELI transaction completes. Requires an arcade to be specified",
+ fields: ["arcadeId"],
+ },
+];
diff --git a/src/constants/greetings.json b/src/constants/greetings.json
index cddc393..31103a7 100644
--- a/src/constants/greetings.json
+++ b/src/constants/greetings.json
@@ -635,5 +635,25 @@
"author": "superaustin7",
"header": "Why does
need Konami Original Songs?",
"comment": "We ❤️ Pop'n Music!"
+ },
+ {
+ "author": "57z",
+ "header": ", I once again am asking you to",
+ "comment": "submit welcome greetings."
+ },
+ {
+ "author": "Anonymous",
+ "header": "Welcome to StepManiaX, !",
+ "comment": "Kyle Ward will sue"
+ },
+ {
+ "author": "Dadrewster569",
+ "header": "Konnichihello, ",
+ "comment": ""
+ },
+ {
+ "author": "superaustin7",
+ "header": "Welcome to jubeat, ",
+ "comment": "THAT WON'T MAKE IT IN TIME FOR THIS SCHEDULE."
}
]
diff --git a/src/layouts/LayoutAuthenticated.vue b/src/layouts/LayoutAuthenticated.vue
index f021358..4cd6849 100644
--- a/src/layouts/LayoutAuthenticated.vue
+++ b/src/layouts/LayoutAuthenticated.vue
@@ -10,13 +10,14 @@ import {
PhFilmSlate,
PhArchive,
PhGitMerge,
+ PhCode,
+ PhDiscordLogo,
+ PhTextAa,
} from "@phosphor-icons/vue";
-import { ref, watch, onMounted, computed } from "vue";
+import { ref, computed } from "vue";
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/Modal/LoadingModal.vue";
// import EmailModal from "@/components/Modal/EmailModal.vue";
import UpdateModal from "@/components/Modal/UpdateModal.vue";
import WelcomeModal from "@/components/Modal/WelcomeModal.vue";
@@ -26,75 +27,20 @@ import NavBarItemPlain from "@/components/NavBarItemPlain.vue";
import AsideMenu from "@/components/Menus/AsideMenu.vue";
import FooterBar from "@/components/FooterBar.vue";
import { gameData } from "@/constants";
-// import BaseButton from "@/components/BaseButton.vue";
+import BaseButton from "@/components/BaseButton.vue";
+const DISCORD_URL = import.meta.env.VITE_DISCORD_URL;
+const DOCS_URL = import.meta.env.VITE_DOCS_URL;
const router = useRouter();
const route = useRoute();
const mainStore = useMainStore();
-onMounted(async () => {
- try {
- const validSession = await mainStore.loadUser();
- if (!validSession) {
- mainStore.deleteUserSession();
- router.push({
- name: "login",
- });
- }
- } catch (error) {
- console.error("Failed to check SessionID:", error);
- mainStore.deleteUserSession();
- router.push({
- name: "login",
- });
- }
-});
-const loading = ref(mainStore.activeRequests !== 0);
-const saving = ref(mainStore.activeSavingRequests !== 0);
-const errorCode = ref(mainStore.errorCode);
-const userLoaded = ref(mainStore.userLoaded);
-const userArcades = ref(mainStore.userArcades);
-
-watch(
- () => mainStore.activeRequests !== 0,
- (newValue) => {
- loading.value = newValue;
- },
-);
-
-watch(
- () => mainStore.activeSavingRequests !== 0,
- (newValue) => {
- saving.value = newValue;
- },
-);
-
-watch(
- () => mainStore.errorCode,
- (newValue) => {
- errorCode.value = newValue;
- },
-);
-
-watch(
- () => mainStore.userLoaded,
- (newValue) => {
- userLoaded.value = newValue;
- },
-);
-
-watch(
- () => mainStore.userArcades,
- (newValue) => {
- userArcades.value = newValue;
- },
-);
+const userLoaded = computed(() => mainStore.userLoaded);
+const userCustomize = computed(() => mainStore.userCustomize);
const layoutAsidePadding = "xl:pl-60";
-const styleStore = useStyleStore();
-
const isAsideMobileExpanded = ref(false);
const isAsideLgActive = ref(false);
@@ -224,6 +170,14 @@ const menuAside = computed(() => {
label: "Changelog Archive",
});
+ if (mainStore.userAdmin) {
+ sideMenu.push({
+ label: "Developer Portal",
+ icon: PhCode,
+ to: "/developer",
+ });
+ }
+
return sideMenu;
});
@@ -232,23 +186,12 @@ const menuAside = computed(() => {
-
-
-
+
+
@@ -285,14 +228,26 @@ const menuAside = computed(() => {
-
-
-
+
+
+
+
+
+
-import { useMainStore } from "@/stores/main.js";
-import { useStyleStore } from "@/stores/style.js";
-import { ref, watch } from "vue";
-import LoadingModal from "@/components/Modal/LoadingModal.vue";
-const mainStore = useMainStore();
-
-const loading = ref(mainStore.isLoading);
-const saving = ref(mainStore.isSaving);
-const errorCode = ref(mainStore.errorCode);
-const styleStore = useStyleStore();
-
-watch(
- () => mainStore.isLoading,
- (newValue) => {
- loading.value = newValue;
- },
-);
-
-watch(
- () => mainStore.isSaving,
- (newValue) => {
- saving.value = newValue;
- },
-);
-
-watch(
- () => mainStore.errorCode,
- (newValue) => {
- errorCode.value = newValue;
- },
-);
-
+
-
-
+
-
diff --git a/src/router/index.js b/src/router/index.js
index b74e6fe..1ca9235 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,9 +1,11 @@
import { createRouter, createWebHistory } from "vue-router";
+import { useMainStore } from "@/stores/main";
import Home from "@/views/HomeView.vue";
const routes = [
{
meta: {
+ requiresAuth: true,
title: "Dashboard",
},
path: "/",
@@ -12,6 +14,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "News Archive",
},
path: "/news",
@@ -20,6 +23,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "News Post",
},
path: "/news/:id",
@@ -28,6 +32,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "WebUI Changelog",
},
path: "/changelog",
@@ -60,6 +65,16 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ title: "Authorize an App",
+ },
+ path: "/profile/authorize",
+ name: "authorize_service",
+ component: () => import("@/views/Auth/AuthorizeView.vue"),
+ },
+ {
+ meta: {
+ requiresAuth: true,
title: "Profile",
},
path: "/profile",
@@ -68,6 +83,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Customizations",
},
path: "/profile/customize",
@@ -76,6 +92,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Integrations",
},
path: "/profile/integrate",
@@ -84,6 +101,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Integration Callback",
},
path: "/profile/integrate/:service",
@@ -92,6 +110,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Login Cards",
},
path: "/profile/cards",
@@ -100,6 +119,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Claim a Profile",
},
path: "/profile/claim",
@@ -108,6 +128,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Data Export",
},
path: "/profile/export",
@@ -124,6 +145,7 @@ const routes = [
// },
{
meta: {
+ requiresAuth: true,
title: "Play Videos",
},
path: "/profile/videos",
@@ -132,6 +154,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Game Images",
},
path: "/profile/content",
@@ -140,6 +163,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "View User",
},
path: "/profiles/:id",
@@ -151,6 +175,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "Admin Dashboard",
},
path: "/admin",
@@ -159,6 +185,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "Onboarding",
},
path: "/admin/onboarding",
@@ -167,6 +195,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "Auto-Onboarding",
},
path: "/admin/onboarding/:data",
@@ -175,6 +205,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "Network Maintenance",
},
path: "/admin/maint",
@@ -183,6 +215,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "Events",
},
path: "/admin/events",
@@ -191,6 +225,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "Data API",
},
path: "/admin/api",
@@ -199,6 +235,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "Arcades",
},
path: "/admin/arcades",
@@ -207,6 +245,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "Users",
},
path: "/admin/users",
@@ -215,6 +255,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "News",
},
path: "/admin/news",
@@ -223,6 +265,8 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
+ requiresAdmin: true,
title: "OTA Updates",
},
path: "/admin/ota",
@@ -239,6 +283,7 @@ const routes = [
// },
{
meta: {
+ requiresAuth: true,
title: "Arcade Overview",
},
path: "/arcade/:id",
@@ -247,6 +292,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Event Settings",
},
path: "/arcade/:id/events",
@@ -258,6 +304,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Machine List",
},
path: "/arcade/:id/machines",
@@ -269,6 +316,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "PASELI Transactions",
},
path: "/arcade/:id/paseli",
@@ -280,6 +328,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Claim an Arcade",
},
path: "/arcade/claim",
@@ -288,6 +337,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Game Overview",
},
path: "/games/:id/",
@@ -299,6 +349,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "View Profile",
},
path: "/games/:game/profiles/:userId/",
@@ -310,6 +361,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Edit Profile",
},
path: "/games/:game/edit",
@@ -321,6 +373,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Rivals",
},
path: "/games/:game/rivals",
@@ -332,6 +385,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Song Overview",
},
path: "/games/:game/song/:songId",
@@ -343,6 +397,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "View Scores",
},
path: "/games/:game/scores/:userId",
@@ -354,6 +409,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Network Scores",
},
path: "/games/:game/scores",
@@ -365,6 +421,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Error",
},
path: "/:catchAll(.*)",
@@ -373,6 +430,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "View Records",
},
path: "/games/:game/records/:userId",
@@ -384,6 +442,7 @@ const routes = [
},
{
meta: {
+ requiresAuth: true,
title: "Network Records",
},
path: "/games/:game/records",
@@ -395,11 +454,23 @@ const routes = [
},
{
meta: {
- title: "Error",
+ requiresAuth: true,
+ requiresDev: true,
+ title: "Developer Portal",
},
- path: "/:catchAll(.*)",
- name: "ErrorPage",
- component: () => import("@/views/ErrorView.vue"),
+ path: "/developer",
+ name: "Developer Portal",
+ component: () => import("@/views/Developer/PortalView.vue"),
+ },
+ {
+ meta: {
+ requiresAuth: true,
+ requiresDev: true,
+ title: "App Registration",
+ },
+ path: "/developer/register",
+ name: "App Registration",
+ component: () => import("@/views/Developer/RegisterView.vue"),
},
];
@@ -411,4 +482,48 @@ const router = createRouter({
},
});
+router.beforeEach(async (to) => {
+ const mainStore = useMainStore();
+ mainStore.errorCode = null;
+
+ if (to.meta.requiresAuth) {
+ const validSession = await mainStore.loadUser();
+
+ if (!validSession) {
+ mainStore.deleteUserSession();
+
+ return {
+ name: "login",
+ query: { redirect: to.fullPath },
+ };
+ }
+ }
+
+ if (to.meta.requiresAdmin) {
+ const validSession = await mainStore.loadUser();
+
+ if (!validSession || !mainStore.userAdmin) {
+ console.log("You're not an admin!");
+ window.alert("You're not an admin!");
+ return {
+ name: "dashboard",
+ };
+ }
+ }
+
+ if (to.meta.requiresDev) {
+ const validSession = await mainStore.loadUser();
+
+ if (!validSession || !mainStore.userAdmin) {
+ console.log("You're not a dev!");
+ window.alert("You're not a dev!");
+ return {
+ name: "dashboard",
+ };
+ }
+ }
+
+ return true;
+});
+
export default router;
diff --git a/src/stores/api/account.js b/src/stores/api/account.js
index 0161e38..8814d53 100644
--- a/src/stores/api/account.js
+++ b/src/stores/api/account.js
@@ -288,8 +288,9 @@ export async function APIUserReadNews(newsId) {
newsId: newsId,
});
- mainStore.userLoaded = false;
- await mainStore.loadUser();
+ const seen_news = await mainStore.userData.seen_news;
+ seen_news[newsId] = true;
+
return data;
} catch (error) {
console.log(`Error saving user!`, error);
diff --git a/src/views/Auth/AuthorizeView.vue b/src/views/Auth/AuthorizeView.vue
new file mode 100644
index 0000000..c44dbfd
--- /dev/null
+++ b/src/views/Auth/AuthorizeView.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+

+
PhaseII
+
+
+
+
Authorize App
+
+
+
+
+
+
+
+
diff --git a/src/views/Auth/LoginView.vue b/src/views/Auth/LoginView.vue
index 5471a4f..a864755 100644
--- a/src/views/Auth/LoginView.vue
+++ b/src/views/Auth/LoginView.vue
@@ -1,5 +1,5 @@
diff --git a/src/views/Developer/PortalView.vue b/src/views/Developer/PortalView.vue
new file mode 100644
index 0000000..56beace
--- /dev/null
+++ b/src/views/Developer/PortalView.vue
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+ Welcome to the PhaseII Developer Portal!
+
+ You're gonna do great 😄
+
+
+ If you're just now getting started, please read the
+
+ developer docs
+
+
+
+ Create or manage your applications below
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+ {{ appInfo.name }}
+
+ OAuth Enabled
+ {{ appInfo.webhooks?.length || 0 }} Webhook(s)
+
+
+
+
+
+
+
diff --git a/src/views/Developer/RegisterView.vue b/src/views/Developer/RegisterView.vue
new file mode 100644
index 0000000..c7a1676
--- /dev/null
+++ b/src/views/Developer/RegisterView.vue
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ intent.tip ?? "" }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ webhook.name }}
+
+ {{ webhook.endpoint }}
+
+
+ {{ field }}: {{ value }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/Game/GameView.vue b/src/views/Game/GameView.vue
index cf4aec0..5618a3b 100644
--- a/src/views/Game/GameView.vue
+++ b/src/views/Game/GameView.vue
@@ -20,9 +20,7 @@ import { getGameInfo } from "@/constants";
import { dashCode } from "@/constants/userData";
import { getIIDXDan } from "@/constants/danClass";
import { formatSortableDate } from "@/constants/date";
-import { useMainStore } from "@/stores/main";
-const mainStore = useMainStore();
const $route = useRoute();
const $router = useRouter();
var gameID = null;
@@ -44,15 +42,9 @@ const versionForm = reactive({
watch(
() => versionForm.currentVersion,
() => {
- mainStore.continueLoad = true;
- mainStore.isLoading = true;
- mainStore.activeRequests = 1;
loadGame(versionForm.currentVersion, profiles.length != 0);
loadProfile();
musicIds.value = [];
- mainStore.continueLoad = false;
- mainStore.isLoading = false;
- mainStore.activeRequests = 0;
},
);
@@ -69,12 +61,8 @@ if (thisGame == null) {
}
onMounted(async () => {
- mainStore.continueLoad = true;
await loadProfile();
await loadGame(null, profiles.length == 0);
- mainStore.continueLoad = false;
- mainStore.isLoading = false;
- mainStore.activeRequests = 0;
});
async function loadGame(version, noUsers) {
diff --git a/src/views/Profile/CustomizeView.vue b/src/views/Profile/CustomizeView.vue
index 2179eaa..1668115 100644
--- a/src/views/Profile/CustomizeView.vue
+++ b/src/views/Profile/CustomizeView.vue
@@ -147,6 +147,18 @@ async function revert() {
/>
+
+
+
+